home *** CD-ROM | disk | FTP | other *** search
/ Power CD / Power CD ATARI-Rechner Lieben.iso / UTILITY / LSRC_222 / LHARC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-29  |  80.4 KB  |  4,699 lines

  1.  
  2. #include "lharc.h"
  3.  
  4. #define VERSION    "2.22"
  5. #define __030    0
  6. #define BETA    0
  7. #define GERMAN    1
  8.  
  9. #ifdef __SHELL__
  10. #undef GERMAN
  11. #undef BETA
  12. #define GERMAN    0
  13. #define    BETA    0
  14. #endif
  15.  
  16. #if GERMAN
  17.     #include "usageger.h"
  18. #else
  19.     #include "usageeng.h"
  20. #endif
  21.  
  22. uchar *errmes[]={
  23. M_UNKNOWNERR,M_INVCMDERR,M_MANYPATERR,M_NOARCNMERR,M_NOFNERR,M_NOARCERR,M_RENAMEERR,M_MKTMPERR,
  24. M_DUPFNERR,M_TOOMANYERR,M_TOOLONGERR,M_NOFILEERR,M_MKFILEERR,M_RDERR,M_WTERR,M_MEMOVRERR,M_INVSWERR,
  25. M_CTRLBRK,M_NOMATCHERR,M_COPYERR,M_NOTLZH,M_OVERWT,M_MKDIR,M_MKDIRERR,M_CRCERR,M_RDONLY};
  26.  
  27. ushort    left[2*NC-1],right[2*NC-1];
  28. uchar    c_len[NC],pt_len[NPT],*len;
  29. ushort    c_freq[2*NC-1],c_code[NC],p_freq[2*NP-1],pt_table[256],pt_code[NPT],t_freq[2*NT-1];
  30. ushort    *freq,len_cnt[17];
  31. int        heap[NC+1];
  32.  
  33. _DTA    _dta;
  34. XATTR    xattr;
  35. FILE    *file1,*file2,*file3,*StdOut=stdout;
  36. int     args,c_err,skipped,cmd,cmdupdate,cmdlist,errorlevel,oldtos;
  37. int        _gemdos,Nfile,fbfiles,cpu;
  38. long    arcpos0,arcpos1,lastarcpos,lastarclen,nextarcpos,arclen,maxlen,old_afx;
  39. long    act_len,file_len,bsize,o_handle=-1,i_handle=-1,o_dev=-1,i_dev=-1;
  40. uchar    act_dir[MAXPATH],basedir[MAXPATH],workdir[MAXPATH],incldir[MAXPATH];
  41. uchar    *unpack="*.ZOO,*.ZIP,*.AR[CJ],*.LZ[HS],*.LHA,*.TAZ";
  42. uchar    *infname,*outfname,*fbuf,*fbnxt,*o_dir;
  43. ulong    fblft,fbmax;
  44. filebuf    *fblast;
  45.  
  46. uchar    SystemId,has_crc,back_1,back_2;
  47. int     patno,exno,maxblk=64,UnixArc,UnixFile,regcnt,wild_arc,multi_arc,all;
  48. int        fn_name=12,pt_name=128,Case=_PC_CASECONV,min_len,garbage,Device;
  49.  
  50. int     n,heapsize,hdr_len,header_len,ignfile;
  51. uchar    *buf=text_buf,*pager,*com_name,*buffer_start,*buffer_last,pack;
  52. uchar    flg_r,flg_p,flg_x,flg_m,flg_a,flg_c,flg_v,flg_w,flg_z,flg_g,flg_L=2,flg_N,flg_B,flg_W,flg_5;
  53. uchar    flg_d,flg_u,flg_s,flg_e,flg_unpacked,ex_len,flg_j,flg_chk,flg_S,flg_R,flg_I,flg_U=1,flg_K;
  54. uchar    flg_t,flg_arc,flg_h,flg_i,flg_backup,flg_f,flg_4,flg_q,flg_A,flg_X,pnt='.',buffered;
  55. uchar    method=5,FlgMethod=5,copying,obj,ptitel,pargs;
  56. char    flg_k=-1;
  57.  
  58. uchar    swi[]="UwCrpxmacntvhifzedgjqsLSRBAWXKybluok54PMNI";
  59. uchar    *swipos[]={&flg_U,&flg_w,&flg_chk,&flg_r,&flg_p,&flg_x,&flg_m,&flg_a,&flg_c,&flg_n,&flg_t,&flg_v,&flg_h,&flg_i,
  60.         &flg_f,&flg_z,&flg_e,&flg_d,&flg_g,&flg_j,&flg_q,&flg_s,&flg_L,&flg_S,&flg_R,&flg_B,&flg_A,&flg_W,&flg_X,&flg_K};
  61.  
  62. #define    SWI_CNT    30
  63.  
  64. LzHead    Hdr1,Hdr2;
  65. _DOSTIME arcstamp,newer;
  66.  
  67. uchar    arcname[MAXPATH],pathname[MAXPATH],backup1[MAXPATH],backup2[MAXPATH];
  68. uchar    filename[MAXPATH],dosfilename[MAXPATH],matchfilename[MAXPATH],comment[MAXCOMMENT+256];
  69. uchar    buffer[(BUFFERSIZ+128+32)<<2],*buffer_1,*buffer_2,*buffer_3,*buffer_gen;
  70. uchar    travel_wild[MAX_PAT],*exclude_file[MAX_EXCLD],fileregbuf[FILEBUFSIZ],*fileptr;
  71. uchar    *travel_path[MAX_PAT],travel_rel[MAX_PAT];
  72. int     patcnt[MAX_PAT],travel_len[MAX_PAT],travel_file[MAX_PAT],arc_file[MAX_ARC];
  73.  
  74. #if BETA
  75. long timer;
  76. #define INIT_TIMER    timer=clock()
  77. #define EXIT_TIMER    timer=clock() - timer; if (!flg_q) printf(" Time : %ld ms \n",(timer*5))
  78. #else
  79. #define INIT_TIMER
  80. #define EXIT_TIMER
  81. #endif
  82.  
  83. clock_t now;
  84.  
  85. void getnow(void)
  86. {
  87.     now=*((unsigned long *) 0x4baL);
  88. }
  89.  
  90. clock_t clock(void)
  91. {
  92.     (void) Supexec(getnow);
  93.     return (now);
  94. }
  95.  
  96. #define  A          16807L
  97. #define  M   2147483647L
  98. #define  Q       127773L
  99. #define  R         2836L
  100.  
  101. long _lseed;
  102.  
  103. int temp(void)
  104. {
  105.     _lseed=A * ((_lseed % Q) + R) - R * (_lseed / Q);
  106.  
  107.     if (_lseed<0)
  108.         _lseed+=M;
  109.  
  110.     return((int) _lseed & 4095);}
  111.  
  112. #define multi_wild(f)    (strchr((f),',')!=NULL)
  113.  
  114. int wildcard(uchar *file)
  115. {
  116.     if (!flg_W && strpbrk(file,"*?[]@|^"))
  117.         return(SUCCS);
  118.     else
  119.         return(FAULT);
  120. }
  121.  
  122. void InitTree(void)
  123. {
  124.     register int i,nil_2=NIL<<1,*p;
  125.  
  126.     p=dad;
  127.     for (i=N;--i>=0;)
  128.         *p++=nil_2;
  129.  
  130.     p=&rson[N+1];
  131.     for (i=256;--i>=0;)
  132.         *p++=nil_2;
  133. }
  134.  
  135. int LSeek(FILE *fp, long offset, int origin)
  136. {
  137.     register long pos,realpos,count;
  138.     register unsigned int f;
  139.     register int rv;
  140.  
  141.     f=(fp->_flag&=~_IOEOF);
  142.     count=fp->_cnt;
  143.     
  144.     if ((f & _IOWRT) || (count==0) || (origin==SEEK_END))
  145.     {
  146.         rv=fflush(fp);
  147.         return(((rv==EOF) || (Fseek(offset,fp->_file,origin)<0)) ? -1 : 0);
  148.     }
  149.  
  150.     if ((realpos=Fseek(0l,fp->_file,SEEK_CUR))<0)
  151.         return(-1);
  152.     pos=offset + count - realpos;
  153.  
  154.     if ((!(f & _IORW)) && (pos<=count) && (pos>=(fp->_base-fp->_ptr)))
  155.  
  156.     {
  157.         fp->_ptr+=pos;
  158.         fp->_cnt-=pos;
  159.         return(0);
  160.     }
  161.     else
  162.     {
  163.         fp->_ptr=fp->_base;
  164.         fp->_cnt=0;
  165.         if (f & _IORW)
  166.             fp->_flag=(f & (~_IOREAD));
  167.         return((Fseek(offset,fp->_file,origin)<0) ? -1 : 0);
  168.     }
  169. }
  170.  
  171. int sseek(FILE *file,long pos,int end)
  172. {
  173.     if (pos>=arclen || LSeek(file,pos,SEEK_SET))
  174.     {
  175.         if (end)
  176.             LSeek(file,0l,SEEK_END);
  177.         return(-1);
  178.     }
  179.     else
  180.         return(0);
  181. }
  182.  
  183. void message(uchar *p,uchar *q)
  184. {
  185.     if (!flg_q)
  186.         printf("%s: %s\n",p,q);
  187. }
  188.  
  189. #if __030
  190. void get_cpu(long cookie, long *value)
  191. {
  192.     register long old_stack,*cookiejar;
  193.  
  194.     cpu=0;
  195.  
  196.     old_stack = Super (NULL);
  197.     cookiejar = *((long **) 0x5a0l);
  198.     Super ((void *) old_stack);
  199.  
  200.     if (cookiejar)
  201.     {
  202.         while (*cookiejar)
  203.         {
  204.             if (*cookiejar==(long) '_CPU')
  205.             {
  206.                 cpu=(int) (*++cookiejar);
  207.                 return;
  208.             }
  209.             cookiejar += 2;
  210.         }
  211.     }
  212. }
  213. #endif
  214.  
  215. int slash(uchar *path,int set)
  216. {
  217.     register int len;
  218.  
  219.     if (path)
  220.         if ((len=(int) strlen(path) - 1)>=0)
  221.         {
  222.             path+=len;
  223.  
  224.             if (*path++!='\\')
  225.             {
  226.                 if (set>0)
  227.                 {
  228.                     *path++='\\';
  229.                     *path++='\0';
  230.                 }
  231.                 else
  232.                     return(SUCCS);
  233.             }
  234.             else if (!set)
  235.                 *--path='\0';
  236.         }
  237.  
  238.     return(FAULT);
  239. }
  240.  
  241. uchar _proc_str[]="\r         : %3d%% (%Nld/%Nld)";
  242. uchar _frozen_str[]="\r         : %Nld -> %Nld (%3d%%) \n";
  243.  
  244. void proc_ind(void)
  245. {
  246.     if ((act_len+=blocksize)>=file_len || blkcnt<=0)
  247.         printf(_proc_str,100,file_len,file_len);
  248.     else
  249.         printf(_proc_str,(int) ((act_len*100l)/file_len),act_len,file_len);
  250.     fflush(stdout);
  251. }
  252.  
  253. int arc_ext(uchar *x)
  254. {
  255.     x++;
  256.  
  257.     if (stricmp("LZH",x) && stricmp("LHA",x) && stricmp("LZS",x))
  258.         return(FAULT);
  259.     else
  260.         return(SUCCS);
  261. }
  262.  
  263. int path_conf(uchar *path,int mode)
  264. {
  265.     if (get_fname(path)>path)
  266.         return((int) pathconf(path,mode));
  267.     else
  268.         return((int) pathconf(act_dir,mode));
  269. }
  270.  
  271. int case_sensitive(uchar *path)
  272. {
  273.     if (path_conf(path,-1)<_PC_CASE)
  274.         return(_PC_CASECONV);
  275.     else
  276.         return((int) path_conf(path,_PC_CASE));
  277. }
  278.  
  279. #ifndef __SHELL__
  280. void wait_for_key(int newline)
  281. {
  282.     if (flg_h && i_handle<0 && o_handle<0)
  283.     {
  284.         printf(M_PRESSKEY);
  285.         fflush(stdout);
  286.  
  287.         fflush(stdin);
  288.         getch();
  289.  
  290.         if (newline)
  291.             new_line();
  292.     }
  293. }
  294. #endif
  295.  
  296. void lha_exit(void)
  297. {
  298. #ifndef __SHELL__
  299.     if (i_handle>=0)
  300.     {
  301.         if (i_dev>=0)
  302.             Fforce(0,(int) i_dev);
  303.         Fclose((int) i_handle);
  304.     }
  305.  
  306.     if (o_handle>=0)
  307.     {
  308.         if (o_dev>=0)
  309.             Fforce(1,(int) o_dev);
  310.         Fclose((int) o_handle);
  311.     }
  312.  
  313.     if (flg_K)
  314.     {
  315.         register long time=clock()+(CLK_TCK>>2);
  316.  
  317.         for (flg_K<<=2;flg_K>0;flg_K--)
  318.         {
  319.             while (clock()<time);
  320.             time+=(CLK_TCK>>2);
  321.             Cconout(7);
  322.         }
  323.     }
  324.  
  325.     wait_for_key(1);
  326.     exit(errorlevel);
  327. #endif
  328. }
  329.  
  330. #define close(f)    if (f!=NULL) fclose(f);f=NULL
  331.  
  332. void error(int errcode,uchar *p,int err)
  333. {
  334.     if (err && old_afx)
  335.         afxonoff(old_afx);
  336.  
  337.     if (copying)
  338.     {
  339.         if (!flg_q)
  340.             printf("\n%s\n",M_COPYERR);
  341.         close(file1);
  342.         unlink(arcname);
  343.     }
  344.  
  345.     if (!flg_q)
  346.     {
  347.         new_line();
  348.  
  349.         if (p)
  350.             printf("%s: %s\n",errmes[errcode],p);
  351.         else
  352.             puts(errmes[errcode]);
  353.     }
  354.  
  355.     if (file3 && (err || cmd!='P'))
  356.     {
  357.         close(file3);
  358.         if (!cmdupdate && cmd!='C')
  359.             unlink(pathname);
  360.     }
  361.  
  362.     if (err)
  363.     {
  364.         if (file1)
  365.         {
  366.             close(file1);
  367.             if (!Device && back_1)
  368.                 rename(backup1,arcname);
  369.         }
  370.  
  371.         if (file2)
  372.         {
  373.             close(file2);
  374.             if (!Device && (back_2 || cmd=='C'))
  375.             {
  376.                 if (copying)
  377.                 {
  378.                     register uchar path[MAXPATH];
  379.                     strcpy(backpath(strcpy(path,backup2)),get_fname(arcname));
  380.                     rename(backup2,path);
  381.                 }
  382.                 else
  383.                     unlink(backup2);
  384.             }
  385.         }
  386.     }
  387.  
  388.     switch (errcode)
  389.     {
  390.         case MEMOVRERR:
  391.             errorlevel|=512;
  392.             break;
  393.         case RDERR:
  394.         case RDONLY:
  395.             errorlevel|=8;
  396.             break;
  397.         case WTERR:
  398.             errorlevel|=4;
  399.             break;
  400.         case RENAMEERR:
  401.         case MKDIRERR:
  402.             errorlevel|=16;
  403.             break;
  404.         case MKFILEERR:
  405.         case MKTMPERR:
  406.             errorlevel|=32;
  407.             break;
  408.         case NOFILEERR:
  409.         case NOFNERR:
  410.             errorlevel|=256;
  411.             break;
  412.         case NOARCERR:
  413.         case NOARCNMERR:
  414.             errorlevel|=128;
  415.     }
  416.  
  417.     if (copying)
  418.         errorlevel|=32;
  419.  
  420.     if (err==SUCCS)
  421.         lha_exit();
  422. }
  423.  
  424. FILE *e_fopen(uchar *fname,uchar *buffer,uchar *mode,int errID,int err)
  425. {
  426.     register FILE *f;
  427.  
  428.     if ((f=fopen(fname,mode))==NULL)
  429.     {
  430.         if (errno==EACCES)
  431.             error(RDONLY,fname,err);
  432.         else
  433.             error(errID,fname,err);
  434.     }
  435.     else if (buffer)
  436.         setvbuf(f,buffer,_IOFBF,bsize);
  437.  
  438.     return(f);
  439. }
  440.  
  441. uint get_key(uchar *keys)
  442. {
  443.     register uchar key;
  444.  
  445.     fflush(stdout);
  446.     do
  447.     {
  448.         key=(uchar) toupper((int) getch());
  449. #if GERMAN
  450.         if (key=='J')
  451.             key='Y';
  452. #endif
  453.     } while (!strchr(keys,key));
  454.  
  455.     printf("%c\n",key);
  456.     return(key);
  457. }
  458.  
  459. void ShipOut(void)
  460. {
  461.     ship++;
  462.     shipout();
  463.     ship=0;
  464. }
  465.  
  466. void tstpat(void)
  467. {
  468.     register int i;
  469.  
  470.     if (!Nfile)
  471.     {
  472.         if (!flg_q)
  473.             puts(M_NOFILEERR);
  474.         errorlevel|=256;
  475.         return;
  476.     }
  477.  
  478.     for (i=patno;--i>=0;)
  479.         if (!patcnt[i] && !travel_wild[i])
  480.         {
  481.             if (!flg_q)
  482.                 printf("%s: %s\n",M_NOMATCHERR,&fileregbuf[travel_file[i]]);
  483.             errorlevel|=256;
  484.         }
  485. }
  486.  
  487. void sethdr(uchar *fn,uint attr,_DOSTIME *time,LzHead *h,int name)
  488. {
  489.     register uchar *id;
  490.     register uint l;
  491.  
  492.     memset(h,0,sizeof(LzHead));
  493.  
  494.     l=(uint) strlen(fn);
  495.     if (name==SUCCS && flg_x==2 && *fn!='\\')
  496.     {
  497.         h->Fname[1]='\\';
  498.         memcpy(h->Fname+2,fn,l++);
  499.     }
  500.     else
  501.         memcpy(h->Fname+1,fn,l);
  502.  
  503.     if ((attr & FA_DIR) && (h->Fname[l]!='\\'))
  504.         h->Fname[++l]='\\';
  505.  
  506.     h->Fname[0]=l;
  507.     h->Attr=attr;
  508.     h->Level=flg_k>0 ? flg_k : 0;
  509.     h->Ftime=*time;
  510.     h->HeadSiz=l+22+ex_len;
  511.  
  512.     if (file3)
  513.     {
  514.         h->OrgSiz=textsize=Fseek(0l,file3->_file,SEEK_END);
  515.         Fseek(0l,file3->_file,SEEK_SET);
  516.     }
  517.     else
  518.         h->OrgSiz=textsize=0;
  519.  
  520.     method=FlgMethod;
  521.     codesize=compsize=0;
  522.  
  523.     if (attr & FA_DIR)
  524.         id="-lhd-";
  525.     else if (cmd=='C')
  526.         id="-afx-";
  527.     else if (!method)
  528.         id="-lz5-";
  529.     else if (method==1)
  530.         id="-lh1-";
  531.     else if (method==5)
  532.         id="-lh5-";
  533.     else
  534.         id="-lz4-";
  535.  
  536.     memcpy(h->HeadID,id,5);
  537. }
  538.  
  539. uint make_ext(uchar *dest,uchar *source,uchar id,int last)
  540. {
  541.     register uint len;
  542.  
  543.     if ((len=(uint) strlen(source))>0)
  544.     {
  545.         if (last)
  546.             len+=4;
  547.         else
  548.             len+=3;
  549.  
  550.         *dest++=(uchar) (len&0xff);
  551.         *dest++=(uchar) (len>>8);
  552.         *dest++=id;
  553.  
  554.         while (*source!='\0')
  555.             *dest++=*source++;
  556.  
  557.         if (last)
  558.             *dest++=0xff;
  559.     }
  560.  
  561.     return(len);
  562. }
  563.  
  564. int wthdr(LzHead *h,FILE *file,int rec,int make,int Case,int unpck)
  565. {
  566.     register uchar *ptr,*s,*n=h->Fname+1;
  567.     register uint len=0;
  568.     register ulong size;
  569.     register _DOSTIME time;
  570.  
  571.     if (make)
  572.     {
  573.         if (flg_k>0 && (UnixArc || flg_s))
  574.         {
  575.             register uchar c,s='\\';
  576.  
  577.             ptr=n;
  578.             while ((c=*ptr++)!='\0')
  579.                 if (c==s)
  580.                     ptr[-1]='/';
  581.  
  582.             if (Case==_PC_CASECONV)
  583.                 strlwr(n);
  584.         }
  585.         else
  586.         {
  587.             yen2slash(n);
  588.  
  589.             if (Case==_PC_CASECONV)
  590.                 strupr(n);
  591.         }
  592.  
  593.         if (flg_k>0)
  594.         {
  595.             if (flg_k<2)
  596.                 s=n+h->Fname[0]+ex_len;
  597.             else
  598.             {
  599.                 uchar path[MAXPATH];
  600.  
  601.                 strncpy(path,n,h->Fname[0]);
  602.                 path[h->Fname[0]]='\0';
  603.  
  604.                 len+=make_ext(&h->Fname[3],get_fname(path),0x01,FAULT);
  605.  
  606.                 if ((s=backpath(path))>path)
  607.                 {
  608.                     s[-1]='\0';
  609.                     len+=make_ext(&h->Fname[len+3],path,0x02,SUCCS);
  610.                 }
  611.  
  612.                 s=&h->Fname[len+3];
  613.             }
  614.  
  615.             if (h->Attr!=0x20 || flg_k==2)
  616.             {
  617.                 len+=5;
  618.                 *s++=5;
  619.                 *s++='\0';
  620.                 *s++=0x40;
  621.                 *s++=h->Attr;
  622.                 *s++='\0';
  623.             }
  624.  
  625.              if (*comment)
  626.              {
  627.                  register uint off=make_ext(s,comment,0x3f,SUCCS);
  628.                 len+=off;
  629.                 s+=off;
  630.             }
  631.  
  632.             *s++='\0';
  633.             *s++='\0';
  634.         }
  635.  
  636.         hdr_len=len;
  637.     }
  638.     else
  639.         len=hdr_len;
  640.  
  641.     if (flg_k==1)
  642.         h->PacSiz+=len;
  643.  
  644.     if (flg_k<2)
  645.         ptr=n+h->Fname[0];
  646.     else
  647.         ptr=h->Fname;
  648.  
  649.     *ptr++=(uchar) (crc&0xff);
  650.     *ptr++=(uchar) (crc>>8);
  651.  
  652.     if (flg_k>0)
  653.     {
  654.         if (UnixArc || flg_s)
  655.             *ptr=(uchar) 'U';
  656.         else
  657.             *ptr=(uchar) 'a';
  658.         h->Attr=0x20;
  659.     }
  660.  
  661.     if (flg_k<2)
  662.     {
  663.         len+=h->HeadSiz;
  664.         h->HeadChk=mksum(h,h->HeadSiz+1);
  665.         len+=2;
  666.     }
  667.     else
  668.     {
  669.         len+=26;
  670.         h->HeadSiz=(uchar) (len&0xff);
  671.         h->HeadChk=(uchar) (len>>8);
  672.     }
  673.  
  674.     size=header_len=len;
  675.  
  676.     if (unpck)
  677.         size+=h->OrgSiz;
  678.     else
  679.         size+=(h->OrgSiz>>1);
  680.  
  681.     ilong(&h->PacSiz);
  682.     ilong(&h->OrgSiz);
  683.  
  684.     time=h->Ftime;
  685.     if (flg_k<2)
  686.         ITIME(h->Ftime);
  687.     else
  688.         dos_2_unixtime((void *) &h->Ftime);
  689.  
  690.     if (make && unpck && size>=bsize)
  691.     {
  692.         if (buffered)
  693.         {
  694.             ShipOut();
  695.             LSeek(file,arcpos0,SEEK_SET);
  696.         }
  697.  
  698.         rec=PAC_NO_BUF;
  699.     }
  700.  
  701.     if (rec==PAC_NO_BUF)
  702.     {
  703.         buffered=0;
  704.         if (fwrite((uchar *) h,7,1,file)!=1 || fwrite((uchar *) h+8,(ulong) len-7,1,file)!=1)
  705.             error(WTERR,arcname,SUCCS);
  706.     }
  707.     else
  708.     {
  709.         if (rec==PAC_INIT_BUF)
  710.         {
  711.             if (file->_cnt && fflush(file))
  712.                 error(WTERR,arcname,SUCCS);
  713.  
  714.             if (!buffered)
  715.                 OpenOut();
  716.             else if (outrec.cnt<=(len+32) || (bsize>size && outrec.cnt<=size))
  717.                 ShipOut();
  718.  
  719.             buffer_start=outrec.ptr;
  720.             buffer_last=(outrec.ptr+=len);
  721.             outrec.cnt-=len;
  722.             buffered=1;
  723.         }
  724.  
  725.         memcpy(buffer_start,h,7);
  726.         memcpy(buffer_start+7,((uchar *) h)+8,len-7);
  727.     }
  728.  
  729.     arcpos1=arcpos0 + len;
  730.  
  731.     ilong(&h->PacSiz);
  732.     ilong(&h->OrgSiz);
  733.     h->Ftime=time;
  734.  
  735.     return(rec);
  736. }
  737.  
  738. void unix2dos(uchar *unx,int rel)
  739. {
  740.     register uchar *u=unx,*d=u,c;
  741.  
  742.     yen2slash(unx);
  743.     if (!strncmp(u,"\\dev\\",5))
  744.     {
  745.         u+=5;
  746.  
  747.         if (u[0]!='\0' && (u[1]=='\0' || u[1]=='\\'))
  748.         {
  749.             if (rel)
  750.                 u++;
  751.             else
  752.             {
  753.                 *d++=*u++;
  754.                 *d++=':';
  755.             }
  756.         }
  757.     }
  758.     else if (!strncmp(u,"\\pipe\\",6))
  759.         u+=6;
  760.  
  761.     while ((c=*u++)!='\0')
  762.     {
  763.         if (rel && c==':' && ((d>&unx[1] && d[-2]=='\\') || (d==&unx[1])))
  764.             d=unx;
  765.         else
  766.             *d++=c;
  767.     }
  768.  
  769.     *d++='\0';
  770. }
  771.  
  772. void yen2slash(uchar *p)
  773. {
  774.     register uchar c,s='/';
  775.  
  776.     while ((c=*p++)!='\0')
  777.         if (c==s)
  778.             p[-1]='\\';
  779. }
  780.  
  781. void Convert_Filename(uchar *dest,uchar *source,int conv)
  782. {
  783.     if (source)
  784.         strcpy(dest,source);
  785.     yen2slash(dest);
  786.  
  787.     if (conv<0)
  788.         Case=case_sensitive(dest);
  789.     else if (conv>0)
  790.         TruncFile(dest);
  791.  
  792.     if (!flg_S && Case==_PC_CASECONV)
  793.         strupr(dest);
  794.     else if (conv<0 && (flg_S==2 || (!flg_S && Case==_PC_CASEINSENS)))
  795.         strupr(dest);
  796. }
  797.  
  798. void unix_2_dostime(void *time)
  799. {
  800.     register _DOSTIME *dostime=(_DOSTIME *) time;
  801.     register struct tm *tm;
  802.  
  803.     ilong((ulong *) time);
  804.     if ((tm=localtime((time_t *) time))!=NULL)
  805.     {
  806.         dostime->time=(uint) ((tm->tm_hour<<11)|(tm->tm_min<<5)|(tm->tm_sec>>1));
  807.         dostime->date=(uint) (((tm->tm_year-80)<<9)|(tm->tm_mon<<5)|tm->tm_mday);
  808.     }
  809.     else
  810.         dostime->time=dostime->date=0;
  811. }
  812.  
  813. void dos_2_unixtime(void *time)
  814. {
  815.     register _DOSTIME *dostime=(_DOSTIME *) time;
  816.     register uint val;
  817.     register struct tm tm,*t=&tm;
  818.  
  819.     val=dostime->time;
  820.     t->tm_sec=(val&31)<<1;
  821.     t->tm_min=(val>>=5)&63;
  822.     t->tm_hour=val>>=6;
  823.  
  824.     val=dostime->date;
  825.     t->tm_mday=val&31;
  826.     t->tm_mon=(val>>=5)&15;
  827.     t->tm_year=(val>>=4)+80;
  828.  
  829.     *((time_t *) time)=mktime(t);
  830.     ilong((ulong *) time);
  831. }
  832.  
  833. uchar *gethdr(FILE *arc,LzHead *h)
  834. {
  835.     uchar exthdr[MAXEXT],fname[MAXPATH];
  836.     register uchar *p;
  837.     register uint extsize;
  838.     register int length;
  839.     register long pos,read;
  840.  
  841.     _gethdr:
  842.     *comment='\0';
  843.     lastarcpos=nextarcpos;
  844.     memset(h,0,sizeof(LzHead));
  845.  
  846.     if (fread((uchar *) h,7,1,arc)!=1 || fread((uchar *) h+8,14,1,arc)!=1)
  847.         goto no_hdr;
  848.  
  849.     if (h->Level>2)
  850.         goto no_hdr;
  851.     else if (h->Level==2)
  852.         h->HeadSiz=HDRSIZ2;
  853.     else if    (h->HeadSiz<MINHDR || h->HeadSiz>sizeof(LzHead))
  854.         goto no_hdr;
  855.  
  856.     read=h->HeadSiz+2;
  857.  
  858.     if (fread((uchar *) h+22,read-21,1,arc)!=1)
  859.         goto no_hdr;
  860.  
  861.     ilong(&h->PacSiz);
  862.     ilong(&h->OrgSiz);
  863.  
  864.     if (h->Level<2)
  865.         ITIME(h->Ftime);
  866.     else
  867.         unix_2_dostime((void *) &h->Ftime);
  868. #if 0
  869.     h->Mtime=h->Ftime;
  870. #endif
  871.  
  872.     lastarclen=read+h->PacSiz;
  873.     pos=lastarcpos+read;
  874.  
  875.     if (h->Level<2)
  876.     {
  877.         if (mksum(h,h->HeadSiz)!=h->HeadChk && mksum(h,h->HeadSiz+1)!=h->HeadChk)
  878.             goto no_hdr;
  879.  
  880.         length=h->Fname[0];
  881.         strncpy(filename,&h->Fname[1],length);
  882.         filename[length++]='\0';
  883.     }
  884.     else
  885.     {
  886.         length=0;
  887.         filename[0]='\0';
  888.     }
  889.  
  890.     p=h->Fname+length;
  891.     h->crc=(uint) *p++;
  892.     h->crc|=(uint) (*p++<<8);
  893.     SystemId=*p++;
  894.  
  895.     has_crc=(flg_chk) ? FAULT : SUCCS;
  896.  
  897.     switch(h->HeadSiz-length)
  898.     {
  899.     case (HDRSIZ0-1-2):
  900.         has_crc=FAULT;
  901.     case (HDRSIZ0-1):
  902.         h->Level=0;
  903.         break;
  904.     default:
  905.         if (h->Level==0)
  906.         {
  907.             if (SystemId==EXTEND_UNIX || SystemId==EXTEND_OS68K)
  908.             {
  909. #if 0
  910.                 memcpy(&h->Mtime,p+1,4);
  911.                 unix_2_dostime((void *) &h->Mtime);
  912. #endif
  913.             }
  914.             else
  915.                 h->Level++;
  916.         }
  917.         break;
  918.     }
  919.  
  920.     if (h->Level>0)
  921.     {
  922.         extsize=(uint) *p++;
  923.         extsize|=(uint) (*p++<<8);
  924.  
  925.         while (extsize>0)
  926.          {
  927.              pos+=extsize;
  928.              if (extsize>MAXEXT)
  929.             {
  930.                 if (sseek(arc,pos-2,0))
  931.                     goto no_hdr;
  932.             }
  933.             else if (fread(exthdr,(length=extsize-2),1,arc)!=1)
  934.                 goto no_hdr;
  935.             else
  936.             {
  937.                 length--;
  938.                 switch (exthdr[0])
  939.                 {
  940.     #if 0
  941.                 case 0:        /* common header */
  942.                     break;
  943.     #endif
  944.                 case 1:        /* filename header */
  945.                 case 2:        /* pathname header */
  946.                     if (length>=pt_name)
  947.                         break;
  948.  
  949.                     strncpy(fname,&exthdr[1],length);
  950.  
  951.                     if ((p=strchr(fname,'\xff'))!=NULL)
  952.                         length=(int) (p-fname);
  953.  
  954.                     fname[length]='\0';
  955.  
  956.                     if (exthdr[0]==1)
  957.                     {
  958.                         p=get_fname(filename);
  959.                         if (((int) (p - filename) + length)<pt_name)
  960.                             strcpy(p,fname);
  961.                     }
  962.                     else if (((int) strlen(filename) + length + 1)<pt_name)
  963.                     {
  964.                         if (fname[length-1]!='\\' && fname[length-1]!='/')
  965.                             strcat(fname,"\\");
  966.  
  967.                         strcat(fname,filename);
  968.                         strcpy(filename,fname);
  969.                     }
  970.                     break;
  971.                 case 0x3f:    /* comment */
  972.                     strncpy(comment,&exthdr[1],length);
  973.                     comment[length]='\0';
  974.  
  975.                     if ((p=strchr(comment,'\xff'))!=NULL)
  976.                         *p='\0';
  977.                     break;
  978.                 case 0x40:    /* file attribute */
  979.                     h->Attr=exthdr[1];
  980.                     break;
  981.     #if 0
  982.                 case 0x50:    /* permission */
  983.                 case 0x51:    /* gid and uid */
  984.                 case 0x52:    /* group name */
  985.                 case 0x53:  /* user name */
  986.                     break;
  987.                 case 0x54:  /* last modified time */
  988.                     memcpy(&h->Mtime,&exthdr[1],4);
  989.                     unix_2_dostime((void *) &h->Mtime);
  990.                     break;
  991.     #endif
  992.                 }
  993.             }
  994.  
  995.             read+=extsize;
  996.             if (h->Level<2)
  997.                 h->PacSiz-=extsize;
  998.             else
  999.                 lastarclen+=extsize;
  1000.  
  1001.             extsize=Bgetc(arc);
  1002.             extsize+=(uint) Bgetc(arc)<<8;
  1003.         }
  1004.     }
  1005.  
  1006.     if (strchr("UXHK",SystemId) || strchr(filename,'/'))
  1007.     {
  1008.         UnixArc=SUCCS;
  1009.  
  1010.         if (flg_k<=0)
  1011.         {
  1012.             flg_k=1;
  1013.             ex_len=3;
  1014.         }
  1015.     }
  1016.  
  1017.     yen2slash(filename);
  1018.     unix2dos(strcpy(matchfilename,filename),1);
  1019.  
  1020.     if (matchfilename[0] && matchfilename[1]==':')
  1021.         strcpy(matchfilename,matchfilename+2);
  1022.  
  1023.     if (matchfilename[0]=='\\' && flg_x==3)
  1024.         strcpy(matchfilename,matchfilename+1);
  1025.  
  1026.     if (!strncmp(matchfilename,".\\",2))
  1027.         strcpy(matchfilename,matchfilename+2);
  1028.     else if (!strncmp(matchfilename,"..\\",3))
  1029.         strcpy(matchfilename,matchfilename+3);
  1030.  
  1031.     h->Attr&=0x3f;
  1032.  
  1033.     {
  1034.         register int len=(int) strlen(matchfilename) - 1;
  1035.  
  1036.         if (matchfilename[len]=='\\')
  1037.         {
  1038.             matchfilename[len]='\0';
  1039.             h->Attr=FA_DIR;
  1040.         }
  1041.         else if (tstID(h->HeadID)==6)
  1042.             h->Attr=FA_DIR;
  1043.  
  1044.         if (h->Attr & FA_DIR)
  1045.         {
  1046.             if (h->Attr!=FA_DIR)
  1047.                 h->Attr&=~FA_DIR;
  1048.             else
  1049.             {
  1050.                 h->OrgSiz=h->PacSiz=0;
  1051.                 lastarclen=read;
  1052.             }
  1053.         }
  1054.     }
  1055.  
  1056.     nextarcpos=lastarcpos+lastarclen;
  1057.  
  1058.     if (!flg_S && Case==_PC_CASECONV)
  1059.         strupr(matchfilename);
  1060.  
  1061.     Convert_Filename(dosfilename,matchfilename,1);
  1062.     UnixFile=strcmp(dosfilename,matchfilename);
  1063.  
  1064.     if (flg_S==2 && (!flg_S && Case==_PC_CASEINSENS))
  1065.         strupr(matchfilename);
  1066.  
  1067.     if (!ferror(arc))
  1068.         return(get_fname(matchfilename));
  1069.  
  1070.     no_hdr:
  1071.     if (lastarcpos<(arclen-20))
  1072.     {
  1073.         LSeek(arc,lastarcpos,SEEK_SET);
  1074.  
  1075.         if (search_lzh(arc,NULL,-1))
  1076.         {
  1077.             if (!flg_q)
  1078.             #if GERMAN
  1079.                 puts(" Zerstörte Daten gefunden und Ã¼berlesen");
  1080.             #else
  1081.                 puts(" Garbage found and skipped");
  1082.             #endif
  1083.             garbage++;
  1084.             goto _gethdr;
  1085.         }
  1086.         else if (!flg_q)
  1087.         #if GERMAN
  1088.             printf("Überflüssige Daten am Archivende (%ld Bytes)\n",arclen-lastarcpos);
  1089.         #else
  1090.             printf("Garbage found at the archive-end (%ld bytes)\n",arclen-lastarcpos);
  1091.         #endif
  1092.     }
  1093.  
  1094.     return(NULL);
  1095. }
  1096.  
  1097. int matchpat(uchar *p,register int pat,register int attr)
  1098. {
  1099.     register uchar *name,path[MAXPATH];
  1100.     register int i,k,retcode=FAULT,wild;
  1101.  
  1102.     if (*p=='\0')
  1103.         return(FAULT);
  1104.  
  1105.     if (attr & FA_DIR)
  1106.     {
  1107.         if (flg_f<2)
  1108.         {
  1109.             Nfile++;
  1110.             return(SUCCS);
  1111.         }
  1112.     }
  1113.     else if (flg_f==3)
  1114.         return(FAULT);
  1115.  
  1116.     name=get_fname(p);
  1117.     backpath(strcpy(path,p));
  1118.  
  1119.     for (i=(pat>=0) ? (pat+1) : patno;--i>=0;)
  1120.     {
  1121.         wild=(flg_W) ? flg_W : !travel_file[i];
  1122.  
  1123.         if (flg_p)
  1124.         {
  1125.             if (strcmp(path,travel_path[i]))
  1126.                 continue;
  1127.         }
  1128.         else if (travel_len[i] && strncmp(path,travel_path[i],travel_len[i]))
  1129.             continue;
  1130.  
  1131.         if (all || chk_wild(name,&fileregbuf[travel_file[i]],wild))
  1132.         {
  1133.             for (k=exno;--k>=0;)
  1134.                 if (chk_wild(name,exclude_file[k],0))
  1135.                     break;
  1136.  
  1137.             if (k<0)
  1138.             {
  1139.                 if (pat<0)
  1140.                 {
  1141.                     patcnt[i]++;
  1142.                     retcode=SUCCS;
  1143.                 }
  1144.                 else
  1145.                     return(SUCCS);
  1146.             }
  1147.         }
  1148.  
  1149.         if (pat>=0)
  1150.             break;
  1151.     }
  1152.  
  1153.     if (retcode)
  1154.         Nfile++;
  1155.  
  1156.     return(retcode);
  1157. }
  1158.  
  1159. uint ratio(ulong a,ulong b)
  1160. {
  1161.     register int i;
  1162.  
  1163.     if (!b)
  1164.         return(1000);
  1165.  
  1166.     for (i=0; i<3 && a<0x19999999L; i++)
  1167.         a*=10;
  1168.     for (;i<3;i++)
  1169.         b/=10;
  1170.     a+=b/2;
  1171.     return((uint) (a/b));
  1172. }
  1173.  
  1174. void regfile(uchar *p,uchar *q,_DTA *file,uchar *f)
  1175. {
  1176.     register uchar *s;
  1177.     register filebuf *f0,*f1;
  1178.     register int attr,len;
  1179.     register uchar ch;
  1180.  
  1181.     attr=(oldtos) ? file->dta_attribute^FA_CHANGED : file->dta_attribute;
  1182.     if (attr & FA_DIR)
  1183.         attr=FA_DIR;
  1184.     else
  1185.     {
  1186.         if (flg_arc && !(attr & FA_CHANGED))
  1187.             return;
  1188.         else if (flg_j && file->dta_size==0)
  1189.             return;
  1190.         else if (maxlen>0 && file->dta_size>maxlen)
  1191.             return;
  1192.         else if (cmd=='C' && file->dta_size<=min_len)
  1193.             return;
  1194.     }
  1195.  
  1196.     if (strstr(f,TEMPFILE))
  1197.         return;
  1198.  
  1199.     if (!fbuf)
  1200.     {
  1201.         if ((fbmax=((long) Malloc(-1)))>65536L && flg_L<2)
  1202.             fbmax>>=1;
  1203.         fbuf=fbnxt=Malloc(fbmax);
  1204.  
  1205.         if (!fbuf)
  1206.             error(MEMOVRERR,NULL,SUCCS);
  1207.  
  1208.         *((long *) fbuf)=0l;
  1209.         fblft=(fbmax-=256)-4;
  1210.         fbnxt+=4;
  1211.         fblast=(filebuf *) fbuf;
  1212.     }
  1213.  
  1214.     f1=(filebuf *) fbnxt;
  1215.     strcpy(s=stpcpy(f1->dir,p),f);
  1216.  
  1217.     if (o_dir!=NULL && !strcmp(f1->dir,o_dir))
  1218.         return;
  1219.  
  1220.     f1->time.time=file->dta_time;
  1221.     f1->time.date=file->dta_date;
  1222.  
  1223.     if (flg_N && FTimeToULong(&newer)>FTimeToULong(&f1->time))
  1224.         return;
  1225.  
  1226.     f1->next=NULL;
  1227.     f1->fpos=s-(uchar *) f1;
  1228.     f1->cpos=flg_x ? ((q-p)+f1->dir-(uchar *) f1) : f1->fpos;
  1229.     f1->attr=attr;
  1230.     f1->flag=0;
  1231.     f1->Case=Case;
  1232.     f1->cluster=min_len;
  1233.  
  1234.     if (patno>1 || !flg_x)
  1235.     {
  1236.         f=(uchar *) f1+f1->fpos;
  1237.         f0=(filebuf *) fbuf;
  1238.         ch=*f;
  1239.  
  1240.         while ((f0=f0->next)!=NULL)
  1241.         {
  1242.             p=(uchar *) f0+f0->fpos;
  1243.             if (ch==*p && !strcmp(f,p) && !strcmp((uchar *) f0+f0->cpos,(uchar *) f1+f1->cpos))
  1244.                 return;
  1245.         }
  1246.     }
  1247.  
  1248.     if (fblft<sizeof(filebuf))
  1249.     {
  1250.         ignfile++;
  1251.         return;
  1252.     }
  1253.  
  1254.     len=(int) (strlen(f1->dir)+(f1->dir-(uchar *) f1))+1;
  1255.     len+=len & 1;
  1256.  
  1257.     fblast->next=fbnxt;
  1258.  
  1259.     fblast=(filebuf *) fbnxt;
  1260.     fblft-=len;
  1261.     fbnxt+=len;
  1262.     fbfiles++;
  1263.  
  1264.     if (flg_n!=1 && !(fbfiles & 15))
  1265.     {
  1266.         printf("\b\b\b\b%4d",fbfiles);
  1267.         fflush(stdout);
  1268.     }
  1269. }
  1270.  
  1271. void travel(uchar *p,uchar *q,int pat)
  1272. {
  1273.     _DTA dta,*old;
  1274.     register _DTA *d=&dta;
  1275.     register int done,compare,filesys;
  1276.     register long handle,buf[MAXPATH>>2];
  1277.     register uchar *s,*name;
  1278.     register XATTR *x=&xattr;
  1279.  
  1280.     filesys=(!flg_S && Case==_PC_CASECONV);
  1281.     compare=(flg_S==2 || (!flg_S && Case==_PC_CASEINSENS));
  1282.  
  1283.     if (!_gemdos)
  1284.     {
  1285.         name=(uchar *) &buf[1];
  1286.  
  1287.         if (*p!='\0')
  1288.             handle=Dopendir(p,0);
  1289.         else
  1290.             handle=Dopendir(act_dir,0);
  1291.  
  1292.         if ((handle&0xff000000l)==0xff000000l)
  1293.             return;
  1294.         else
  1295.             done=(int) Dreaddir(MAXPATH,handle,(uchar *) buf);
  1296.     }
  1297.     else
  1298.     {
  1299.         name=d->dta_name;
  1300.  
  1301.         strcat(p,"*.*");
  1302.  
  1303.         old=Fgetdta();
  1304.         Fsetdta(d);
  1305.         done=Fsfirst(p,-1);
  1306.     }
  1307.  
  1308.     s=backpath(p);
  1309.  
  1310.     while (!done)
  1311.     {
  1312.         if (name[0]=='.' && (name[1]=='\0' || (name[1]=='.' && name[2]=='\0')))
  1313.             goto travel_next;
  1314.         else
  1315.         {
  1316.             if (!_gemdos)
  1317.             {
  1318.                 strcpy(s,name);
  1319.                 Fxattr(0,p,(uchar *) x);
  1320.  
  1321.                 d->dta_time=x->ctime;
  1322.                 d->dta_date=x->cdate;
  1323.                 d->dta_size=x->size;
  1324.                 d->dta_attribute=x->attr;
  1325.             }
  1326.         
  1327.             if ((!flg_a && (d->dta_attribute & (FA_HIDDEN|FA_SYSTEM|FA_RDONLY))) || (d->dta_attribute & FA_LABEL))
  1328.                 goto travel_next;
  1329.         }
  1330.  
  1331.         if (d->dta_attribute & FA_DIR)
  1332.         {
  1333.             if (filesys)
  1334.                 strupr(name);
  1335.  
  1336.             if (flg_f>1)
  1337.             {
  1338.                 strcpy(s,name);
  1339.                 if (compare)
  1340.                     strupr(s);
  1341.  
  1342.                 if (matchpat(p,pat,FA_DIR))
  1343.                 {
  1344.                     *s='\0';
  1345.                     regfile(p,q,d,name);
  1346.                 }
  1347.             }
  1348.             else if (flg_f && travel_wild[pat])
  1349.             {
  1350.                 *s='\0';
  1351.                 regfile(p,q,d,name);
  1352.             }
  1353.  
  1354.             if (flg_r && travel_wild[pat])
  1355.             {
  1356.                 strcpy(stpcpy(s,name),"\\");
  1357.  
  1358.                 if (strlen(p)>=pt_name)
  1359.                     message(M_TOOLONGERR,p);
  1360.                 else
  1361.                     travel(p,q,pat);
  1362.             }
  1363.         }
  1364.         else if (flg_f<3)
  1365.         {
  1366.             if (filesys)
  1367.                 strupr(name);
  1368.             strcpy(s,name);
  1369.             if (compare)
  1370.                 strupr(s);
  1371.  
  1372.             if (matchpat(p,pat,0))
  1373.             {
  1374.                 *s='\0';
  1375.                 regfile(p,q,d,name);
  1376.             }
  1377.         }
  1378.  
  1379.         travel_next:
  1380.  
  1381.         if (_gemdos)
  1382.             done=Fsnext();
  1383.         else
  1384.             done=(int) Dreaddir(MAXPATH,handle,(uchar *) buf);
  1385.         *s='\0';
  1386.  
  1387.     }
  1388.  
  1389.     if (_gemdos)
  1390.         Fsetdta(old);
  1391.     else
  1392.         Dclosedir(handle);
  1393. }
  1394.  
  1395. int drive(uchar *path)
  1396. {
  1397.     if (path[0] && path[1]==':')
  1398.     {
  1399.         register int drv=toupper(path[0]);
  1400.  
  1401.         if (__mint && drv=='U')
  1402.         {
  1403.             if (path[2]=='\\' && path[3] && path[4]=='\\')
  1404.                 drv=toupper(path[3]);
  1405.         }
  1406.  
  1407.         if (drv>='A' && drv<='Z')
  1408.             return(drv-'A');
  1409.     }
  1410.  
  1411.     return(Dgetdrv());
  1412. }
  1413.  
  1414. void mklist(void)
  1415. {
  1416.     register _BPB *bpb;
  1417.     register uchar path[MAXPATH],*rel;
  1418.     register int i,new;
  1419.  
  1420.     fbfiles=Nfile=0;
  1421.  
  1422.     for (i=0;i<patno;i++)
  1423.     {
  1424.         if (!flg_q)
  1425.         {
  1426.         #if GERMAN
  1427.             printf("\r Suchmuster : (%d/%d), Dateien gefunden : %4d",i+1,patno,Nfile);
  1428.         #else
  1429.             printf("\r Pattern : (%d/%d), Files matched : %4d",i+1,patno,Nfile);
  1430.         #endif
  1431.             fflush(stdout);
  1432.         }
  1433.  
  1434.         if (!i)
  1435.             new=SUCCS;
  1436.         else
  1437.             new=strcmp(path,travel_path[i]);
  1438.  
  1439.         strcpy(rel=path,travel_path[i]);
  1440.  
  1441.         if (cmd=='C' && new && (bpb=Getbpb(drive(path)))!=NULL)
  1442.             min_len=bpb->clsizb;
  1443.         else
  1444.             min_len=1024;
  1445.  
  1446.         if (pack || flg_X)
  1447.             rel+=strlen(path);
  1448.         else if (travel_rel[i])
  1449.             rel+=travel_rel[i];
  1450.         else
  1451.         {
  1452.             if (*rel && rel[1]==':')
  1453.                 rel+=2;
  1454.  
  1455.             if (*rel=='\\' && flg_x==3)
  1456.                 rel++;
  1457.  
  1458.             if (!strncmp(rel,".\\",2))
  1459.                 rel+=2;
  1460.             else if (!strncmp(rel,"..\\",3))
  1461.                 rel+=3;
  1462.         }
  1463.  
  1464.         if (new)
  1465.         {
  1466.             pt_name=path_conf(path,_PC_PATH_MAX);
  1467.             if (pt_name>MAXPATH)
  1468.                 pt_name=MAXPATH;
  1469.             Case=case_sensitive(path);
  1470.  
  1471.             if (__mint)
  1472.                 _gemdos=(path_conf(path,_PC_NAME_MAX)<=12 && Case==_PC_CASECONV) ? 1 : 0;
  1473.             else
  1474.                 _gemdos=1;
  1475.         }
  1476.  
  1477.         travel(path,rel,i);
  1478.         patcnt[i]=fbfiles-Nfile;
  1479.         Nfile=fbfiles;
  1480.     }
  1481.  
  1482.     Mshrink(fbuf,fbmax-fblft+32);
  1483.  
  1484.     if (!flg_q)
  1485.     {
  1486.         printf("\b\b\b\b%4d\n\n",Nfile);
  1487.         if (ignfile)
  1488.         #if GERMAN
  1489.             printf("Datei-Tabelle voll, %d Datei(en) ignoriert\n",ignfile);
  1490.         #else
  1491.             printf("File table overflow, %d file(s) ignored\n",ignfile);
  1492.         #endif
  1493.     }
  1494. }
  1495.  
  1496. long _proc_size[]={1000000L,
  1497.                    10000000L,
  1498.                    100000000L,
  1499.                    1000000000L};
  1500.  
  1501. void blkdisp(long len,uchar *s,long size)
  1502. {
  1503.     register int i;
  1504.  
  1505.     blocksize=size;
  1506.     blkcnt=(int) ((len+size-1)/size);
  1507.  
  1508.     for (i=0;i<(sizeof(_proc_size)>>2);i++)
  1509.         if (len<_proc_size[i])
  1510.             break;
  1511.  
  1512.     _frozen_str[13]=_frozen_str[21]=(i+'6');
  1513.  
  1514.     if (!flg_n)
  1515.     {
  1516.         register uchar pind[MAXPATH],*p=pind,c=pnt;
  1517.  
  1518.         if (blkcnt>maxblk)
  1519.         {
  1520.             blkcnt=maxblk;
  1521.             blocksize=len/maxblk;
  1522.         }
  1523.         else if (!blkcnt)
  1524.             blkcnt++;
  1525.  
  1526.         for (i=blkcnt;--i>=0;)
  1527.             *p++=c;
  1528.         *p='\0';
  1529.  
  1530.         printf(" %s :    %s\r %s :    ",s,pind,s);
  1531.     }
  1532.     else if (flg_n==2)
  1533.     {
  1534.         memcpy(_proc_str+2,s,8);
  1535.         _proc_str[20]=_proc_str[25]=_frozen_str[13];
  1536.         printf(_proc_str,0,act_len=0,file_len=len);
  1537.     }
  1538.     else if (flg_n==3)
  1539.     {
  1540.         RotInd=0;
  1541.         printf(" %s:   -\b",s);
  1542.     }
  1543.  
  1544.     fflush(stdout);
  1545. }
  1546.  
  1547. void MakeBuffers(void)
  1548. {
  1549.     register long buf,len=0;
  1550.  
  1551.     if (cmdupdate && !flg_u && FlgMethod==5)
  1552.     {
  1553.         if ((buf=(long) malloc(ENCODE5))!=0)
  1554.         {
  1555.             buf=(buf+=63) & (~15L);
  1556.  
  1557.             text=(uchar *) buf;
  1558.             level=(uchar *) (buf+=TEXT);
  1559.             childcount=(uchar *) (buf+=LEVEL);
  1560.             position=(short *) (buf+=CHILDCOUNT);
  1561.             parent=(short *) (buf+=POSITION);
  1562.             prev=(short *) (buf+=PARENT);
  1563.             next=(short *) (buf+=PREV);
  1564.         }
  1565.         else
  1566.             error(MEMOVRERR,NULL,SUCCS);
  1567.     }
  1568.     else if (FlgMethod!=5 || !cmdupdate)
  1569.     {
  1570.         if ((buf=(long) malloc(ENCODE))!=0)
  1571.         {
  1572.             buf=(buf+=63) & (~15L);
  1573.     
  1574.             lson=(int *) buf;
  1575.             rson=(int *) (buf+=LSON);
  1576.             dad=(int *) (buf+=RSON);
  1577.         }
  1578.         else
  1579.             error(MEMOVRERR,NULL,SUCCS);
  1580.     }
  1581.  
  1582.     if (!flg_L)
  1583.     {
  1584.         len=((long) Malloc(-1)>>3) & (~1023l);
  1585.         if (len>MAXBUFFER)
  1586.             len=MAXBUFFER;
  1587.     }
  1588.     else if (flg_L==2)
  1589.     {
  1590.         len=(((long) Malloc(-1)-65536L)>>2) & (~1023l);
  1591.         if (len>MAXBUFFERL2)
  1592.             len=MAXBUFFERL2;
  1593.     }
  1594.  
  1595.     if (len<=BUFFERSIZ || (buf=(long) malloc(((len+=128)<<2)+128))==0)
  1596.     {
  1597.         buf=(long) buffer;
  1598.         len=BUFFERSIZ+128;
  1599.     }
  1600.  
  1601.     buffer_1=(uchar *) ((buf+63) & (~15l));
  1602.     buffer_2=buffer_1+len;
  1603.     buffer_3=buffer_2+len;
  1604.     buffer_gen=buffer_3+len;
  1605.     bsize=len-128;
  1606. }
  1607.  
  1608. void freeze(uchar *p,int attr,int file,int Case)
  1609. {
  1610.     register int rec=PAC_INIT_BUF,unpck=(flg_u || (Hdr2.OrgSiz<=40 && !flg_5));
  1611.     register long arcpos;
  1612.  
  1613.     crc=ship=0;
  1614.  
  1615.     if (!unpck && flg_U && !flg_5 && chk_wild(get_fname(p),unpack,0))
  1616.         unpck=SUCCS;
  1617.  
  1618.     if (FTimeToULong(&arcstamp)<FTimeToULong(&Hdr2.Ftime))
  1619.         arcstamp=Hdr2.Ftime;
  1620.  
  1621.     if (!flg_q)
  1622.     {
  1623.         if (file>0)
  1624.             printf("(%d/%d): ",file,Nfile);
  1625.  
  1626.         if (attr & FA_DIR)
  1627.             printf("%s: Directory\n",p);
  1628.         else
  1629.             puts(p);
  1630.  
  1631.         if (flg_e)
  1632.             get_comment(stdin);
  1633.     }
  1634.  
  1635.     blkdisp(Hdr2.OrgSiz,(unpck || (attr & FA_DIR)) ? "Storing " : "Freezing",(method==5 && !unpck) ? (N*2) : N);
  1636.  
  1637.     if (attr & FA_DIR)
  1638.     {
  1639.         Hdr2.PacSiz=Hdr2.OrgSiz=0;
  1640.         wthdr(&Hdr2,file2,rec,SUCCS,Case,SUCCS);
  1641.         arcpos0=arcpos1;
  1642.         ProcInd();
  1643.     }
  1644.     else
  1645.     {
  1646.         if (!unpck || cmd!='C')
  1647.             rec=wthdr(&Hdr2,file2,rec,SUCCS,Case,unpck);
  1648.  
  1649.         origsize=textsize=Hdr2.OrgSiz;
  1650.  
  1651.         infile=file3;
  1652.         infname=p;
  1653.  
  1654.         if (unpck)
  1655.             codesize=textsize+1;
  1656.         else if (!method)
  1657.             EncodeOld();
  1658.         else if (method==1)
  1659.             Encode();
  1660.         else if (method==5)
  1661.         {
  1662.             init_encode5();
  1663.             encode5();
  1664.             codesize=compsize;
  1665.         }
  1666.  
  1667.         if (flg_backup)
  1668.         {
  1669.             register int new_attr=attr & (~FA_CHANGED);
  1670.             if (attr!=new_attr)
  1671.                 Fattrib(infname,1,(oldtos) ? new_attr^FA_CHANGED : new_attr);
  1672.         }
  1673.  
  1674.         if (!buffered)
  1675.             rec=PAC_NO_BUF;
  1676.  
  1677.         if (codesize>=origsize || (cmd=='C' && ((origsize+min_len-1)/min_len)<=((codesize+header_len+min_len-1)/min_len)))
  1678.         {
  1679.             flg_unpacked=1;
  1680.  
  1681.             if (cmd!='C')
  1682.             {
  1683.                 arcpos=arcpos1 + Hdr2.OrgSiz;
  1684.                 Hdr2.PacSiz=Hdr2.OrgSiz;
  1685.  
  1686.                 if (!flg_4)
  1687.                     memcpy(Hdr2.HeadID,"-lh0-",5);
  1688.  
  1689.                 if (!unpck)
  1690.                 {
  1691.                     if (buffered)
  1692.                     {
  1693.                         shipout();
  1694.                         rec=PAC_NO_BUF;
  1695.                     }
  1696.  
  1697.                     LSeek(file2,arcpos1,SEEK_SET);
  1698.                     LSeek(file3,0l,SEEK_SET);
  1699.                     copyfile(file3,file2,Hdr2.OrgSiz,0,0);
  1700.                 }
  1701.                 else
  1702.                     copyfile(file3,file2,Hdr2.OrgSiz,1,(rec==PAC_NO_BUF) ? 0 : 1);
  1703.             }
  1704.             else
  1705.             {
  1706.                 while ((long) origsize>0)
  1707.                 {
  1708.                     ProcInd();
  1709.                     origsize-=blocksize;
  1710.                 }
  1711.  
  1712.                 Hdr2.PacSiz=Hdr2.OrgSiz;
  1713.                 goto _freeze_end;
  1714.             }
  1715.         }
  1716.         else
  1717.         {
  1718.             arcpos=arcpos1 + codesize;
  1719.             Hdr2.PacSiz=codesize;
  1720.             flg_unpacked=0;
  1721.         }
  1722.  
  1723.         if (rec==PAC_NO_BUF)
  1724.             LSeek(file2,arcpos0,SEEK_SET);
  1725.         else
  1726.             rec=PAC_EXIT_BUF;
  1727.  
  1728.         wthdr(&Hdr2,file2,rec,FAULT,Case,unpck);
  1729.         arcpos0=arcpos;
  1730.         if (cmd!='C' && (rec==PAC_NO_BUF || !buffered))
  1731.             LSeek(file2,arcpos0,SEEK_SET);
  1732.     }
  1733.  
  1734.     _freeze_end:
  1735.     if (flg_n!=1)
  1736.     {
  1737.         memcpy(_frozen_str+2,(flg_unpacked || (attr & FA_DIR)) ? "Stored:   " : "Frozen:   ",10);
  1738.         printf(_frozen_str,Hdr2.OrgSiz,Hdr2.PacSiz,ratio(Hdr2.PacSiz,Hdr2.OrgSiz)/10);
  1739.     }
  1740.  
  1741.     *comment='\0';
  1742. }
  1743.  
  1744. void get_comment(FILE *f)
  1745. {
  1746.     register int len;
  1747.     register uchar *input=comment,*q;
  1748.  
  1749.     if (f==stdin)
  1750.         puts(M_COMMENT);
  1751.  
  1752.     while (fgets(input,255,f))
  1753.     {
  1754.         if ((q=strchr(input,'\r'))!=NULL || (q=strchr(input,'\n'))!=NULL)
  1755.             *q='\0';
  1756.  
  1757.         if ((len=(int) strlen(input))>0 || f!=stdin)
  1758.         {
  1759.             input+=len;
  1760.             *input++='\n';
  1761.             if (!flg_s)
  1762.                 *input++='\r';
  1763.  
  1764.             if ((int) (input-comment)>=MAXCOMMENT)
  1765.                 break;
  1766.         }
  1767.         else
  1768.             break;
  1769.     }
  1770.  
  1771.     if (input>comment)
  1772.     {
  1773.         if (flg_s)
  1774.             input[-1]='\0';
  1775.         else
  1776.             input[-2]='\0';
  1777.     }
  1778.     else
  1779.         *comment='\0';
  1780. }
  1781.  
  1782. void archive_comment(FILE *output)
  1783. {
  1784.     if (com_name)
  1785.     {
  1786.         register FILE *f;
  1787.  
  1788.         if ((f=fopen(com_name,"r"))!=NULL)
  1789.         {
  1790.             get_comment(f);
  1791.             fclose(f);
  1792.         }
  1793.     }
  1794.     else
  1795.         get_comment(stdin);
  1796.  
  1797.     if (*comment)
  1798.     {
  1799.         uchar buf[MAXCOMMENT+256]=COM_ID;
  1800.         strcat(buf,comment);
  1801.  
  1802.         arcpos0=strlen(buf)+1;
  1803.         if (fwrite(buf,arcpos0,1,output)!=1)
  1804.             error(WTERR,arcname,SUCCS);
  1805.  
  1806.         *comment='\0';
  1807.     }
  1808. }
  1809.  
  1810. void copyold(int buf)
  1811. {
  1812.     infname=arcname;
  1813.     if (FTimeToULong(&arcstamp)<FTimeToULong(&Hdr1.Ftime))
  1814.         arcstamp=Hdr1.Ftime;
  1815.     LSeek(file1,lastarcpos,SEEK_SET);
  1816.  
  1817.     if (buf && buffered)
  1818.     {
  1819.         if (outrec.cnt<=lastarclen)
  1820.         {
  1821.             ShipOut();
  1822.             LSeek(file2,arcpos0,SEEK_SET);
  1823.             copyfile(file1,file2,lastarclen,0,0);
  1824.         }
  1825.         else
  1826.             copyfile(file1,file2,lastarclen,0,1);
  1827.     }
  1828.     else
  1829.         copyfile(file1,file2,lastarclen,0,0);
  1830.     arcpos0+=lastarclen;
  1831. }
  1832.  
  1833. int execappend(void)
  1834. {
  1835.     register filebuf *f0;
  1836.     register uchar *q;
  1837.     register int update,in_arc,cnt=0,file=1;
  1838.  
  1839.     f0=(filebuf *) fbuf;
  1840.     q=file1 ? gethdr(file1,&Hdr1) : NULL;
  1841.  
  1842.     for (;;)
  1843.     {
  1844.         update=FAULT;
  1845.  
  1846.         if (q)
  1847.         {
  1848.             in_arc=SUCCS;
  1849.             f0=(filebuf *) fbuf;
  1850.  
  1851.             while ((f0=f0->next)!=NULL)
  1852.             {
  1853.                 if (!f0->flag && strcmp((uchar *) f0+f0->fpos,q)==0)
  1854.                 {
  1855.                     if (flg_I)
  1856.                         strcpy(backpath(incldir),(uchar *) f0+f0->fpos);
  1857.  
  1858.                     if (strcmp((flg_I) ? incldir : (uchar *) f0+f0->cpos,matchfilename)==0)
  1859.                     {
  1860.                         if (!flg_A)
  1861.                             update=SUCCS;
  1862.                         f0->flag=SUCCS;
  1863.                         break;
  1864.                     }
  1865.                 }
  1866.             }
  1867.         }
  1868.         else
  1869.         {
  1870.             in_arc=FAULT;
  1871.  
  1872.             while ((f0=f0->next)!=NULL)
  1873.             {
  1874.                 if (!f0->flag)
  1875.                 {
  1876.                     if (flg_I)
  1877.                         strcpy(backpath(incldir),(uchar *) f0+f0->fpos);
  1878.                     f0->flag=update=SUCCS;
  1879.                     break;
  1880.                 }
  1881.             }
  1882.  
  1883.             if (!f0)
  1884.                 break;
  1885.         }
  1886.  
  1887.         if (!flg_q)
  1888.         {
  1889.             printf("(%d/%d):\r",file,Nfile);
  1890.             fflush(stdout);
  1891.         }
  1892.  
  1893.         if (update && (!in_arc || flg_c || (FTimeToULong(&Hdr1.Ftime)<FTimeToULong(&f0->time))))
  1894.         {
  1895.             if (f0->attr & FA_DIR)
  1896.                 file3=NULL;
  1897.             else if ((file3=e_fopen(f0->dir,buffer_3,"rb",RDERR,FAULT))==NULL)
  1898.             {
  1899.                 if (in_arc)
  1900.                     copyold(SUCCS);
  1901.                 goto _append_next;
  1902.             }
  1903.  
  1904.             sethdr((flg_I) ? incldir : (uchar *) f0+f0->cpos,f0->attr,&f0->time,&Hdr2,SUCCS);
  1905.             freeze(f0->dir,f0->attr,file,f0->Case);
  1906.             close(file3);
  1907.             cnt++;
  1908.  
  1909.             if (in_arc)
  1910.                 sseek(file1,nextarcpos,1);
  1911.         }
  1912.         else
  1913.             copyold(SUCCS);
  1914.  
  1915.         _append_next:
  1916.         if (q && (q=gethdr(file1,&Hdr1))==NULL)
  1917.             f0=(filebuf *) fbuf;
  1918.  
  1919.         if (update)
  1920.             file++;
  1921.     }
  1922.  
  1923.     return(cnt);
  1924. }
  1925.  
  1926. void delfile(void)
  1927. {
  1928.     filebuf *f0;
  1929.  
  1930.     f0=(filebuf *) fbuf;
  1931.     while ((f0=f0->next)!=NULL)
  1932.     {
  1933.         if (!(f0->attr & FA_DIR))
  1934.             unlink(f0->dir);
  1935.     };
  1936. }
  1937.  
  1938. int search_lzh(FILE *input,FILE *output,int mode)
  1939. {
  1940.     register long len,pos;
  1941.  
  1942.     if (mode<0)
  1943.         pos=ftell(input);
  1944.     else
  1945.         pos=0;
  1946.  
  1947.     _cont_search:
  1948.     if ((len=fread(text_buf,1,4096,input))>0)
  1949.     {
  1950.         register uchar *ptr=text_buf,*last=ptr+len-5,c,s='-';
  1951.  
  1952.         if (mode>=0)
  1953.         {
  1954.             arcpos0=Fseek(0l,input->_file,SEEK_CUR);
  1955.             arclen=Fseek(0l,input->_file,SEEK_END);
  1956.             Fseek(arcpos0,input->_file,SEEK_SET);
  1957.             arcpos0=0;
  1958.         }
  1959.  
  1960.         for (;ptr<last;ptr++)
  1961.             if (*ptr==s && ptr[4]==s)
  1962.             {
  1963.                 c=ptr[1];
  1964.                 if (c=='l' || c=='L' || c=='a' || c=='A')
  1965.                 {
  1966.                     if (ptr>=(text_buf+2))
  1967.                     {
  1968.                         if (output && flg_z)
  1969.                             archive_comment(output);
  1970.  
  1971.                         LSeek(input,nextarcpos=pos+((ptr-2)-text_buf),SEEK_SET);
  1972.                         INIT_TIMER;
  1973.                         return(SUCCS);
  1974.                     }
  1975.                 }
  1976.                 else if (c=='c' && ptr[2]=='o' && ptr[3]=='m')
  1977.                 {
  1978.                     if (output && !flg_z)
  1979.                     {
  1980.                         arcpos0=strlen(ptr)+1;
  1981.                         if (fwrite(ptr,arcpos0,1,output)!=1)
  1982.                             error(WTERR,arcname,SUCCS);
  1983.                     }
  1984.  
  1985.                     if (mode>0 && !flg_q && flg_x && ((cmd!='V' && cmd!='L') || flg_x<2))
  1986.                     {
  1987.                         puts(ptr+5);
  1988.                         new_line();
  1989.                     }
  1990.  
  1991.                     ptr+=strlen(ptr);
  1992.                 }
  1993.             }
  1994.     }
  1995.  
  1996.     if (mode>=0)
  1997.         error(NOFILEERR,arcname,(mode>0) ? 128 : SUCCS);
  1998.     else if (len>0)
  1999.     {
  2000.         pos+=len;
  2001.         goto _cont_search;
  2002.     }
  2003.  
  2004.     return(FAULT);
  2005. }
  2006.  
  2007. int openarc1(long size)
  2008. {
  2009.     back_1=back_2=0;
  2010.  
  2011.     file1=e_fopen(infname=arcname,NULL,"rb",NOARCERR,FAULT);
  2012.     if (file1 && search_lzh(file1,NULL,1))
  2013.     {
  2014.         setvbuf(file1,buffer_1,_IOFBF,size);
  2015.         INIT_TIMER;
  2016.         return(SUCCS);
  2017.     }
  2018.     else
  2019.     {
  2020.         close(file1);
  2021.         return(FAULT);
  2022.     }
  2023. }
  2024.  
  2025. void get_tempname(uchar *path)
  2026. {
  2027.     register uchar *ext;
  2028.  
  2029.     strcat(path,TEMPFILE);
  2030.     ext=path+strlen(path);
  2031.  
  2032.     do
  2033.     {
  2034.         sprintf(ext,"%X",temp());
  2035.     } while (!Fsfirst(path,-1));
  2036. }
  2037.  
  2038. void openbackup1(void)
  2039. {
  2040.     back_1++;
  2041.  
  2042.     backpath(strcpy(backup1,arcname));
  2043.     get_tempname(backup1);
  2044.  
  2045.     if (Frename(0,arcname,infname=backup1))
  2046.         error(RENAMEERR,arcname,SUCCS);
  2047.  
  2048.     file1=e_fopen(backup1,buffer_1,"rb",WTERR,SUCCS);
  2049.     arclen=Fseek(0l,file1->_file,SEEK_END);
  2050.     Fseek(0l,file1->_file,SEEK_SET);
  2051. }
  2052.  
  2053. void openbackup2(void)
  2054. {
  2055.     back_2++;
  2056.  
  2057.     if (Device)
  2058.         strcpy(backup2,arcname);
  2059.     else
  2060.     {
  2061.         if (flg_w)
  2062.             strcpy(backup2,workdir);
  2063.         else
  2064.             backpath(strcpy(backup2,arcname));
  2065.         get_tempname(backup2);
  2066.     }
  2067.  
  2068.     outfile=file2=e_fopen(outfname=backup2,buffer_2,(flg_w) ? "w+b" : "wb",MKTMPERR,SUCCS);
  2069.     INIT_TIMER;
  2070. }
  2071.  
  2072. void stclosearc(FILE *f)
  2073. {
  2074.     if (fflush(f))
  2075.         error(WTERR,arcname,SUCCS);
  2076.  
  2077.     if (flg_t)
  2078.         Fdatime(&arcstamp,f->_file,1);
  2079.  
  2080.     if (fclose(f))
  2081.         error(WTERR,arcname,SUCCS);
  2082. }
  2083.  
  2084. void endofupdate(int cnt)
  2085. {
  2086.     if (file1)
  2087.     {
  2088.         Fdatime(&arcstamp,file1->_file,1);
  2089.         fclose(file1);
  2090.     }
  2091.         
  2092.     tstpat();
  2093.  
  2094.     if (cnt)
  2095.     {
  2096.         if (file1)
  2097.         {
  2098.             if (flg_B)
  2099.             {
  2100.                 register uchar bakname[MAXPATH],*f;
  2101.  
  2102.                 strcpy(bakname,arcname);
  2103.                 if ((f=strrchr(get_fname(bakname),'.'))!=NULL && (arc_ext(f) || f[1]=='\0'))
  2104.                     strcpy(f,".BAK");
  2105.                 else
  2106.                     strcat(bakname,".BAK");
  2107.                 unlink(bakname);
  2108.                 rename(backup1,bakname);
  2109.             }
  2110.             else
  2111.                 unlink(backup1);
  2112.             file1=NULL;
  2113.         }
  2114.  
  2115.         if (arcpos0)
  2116.         {
  2117.             if (fputc(0,file2)==EOF)
  2118.                 error(WTERR,arcname,SUCCS);
  2119.  
  2120.             if (!Device)
  2121.             {
  2122.                 if (flg_w && drive(arcname)!=drive(backup2))
  2123.                 {
  2124.                     if (!flg_q)
  2125.                     #if GERMAN
  2126.                         puts("Kopiere temporäres Archiv...");
  2127.                     #else
  2128.                         puts("Copying Temp to Archive ...");
  2129.                     #endif
  2130.  
  2131.                     file1=e_fopen(outfname=arcname,buffer_1,"wb",MKFILEERR,SUCCS);
  2132.                     LSeek(file2,0l,SEEK_SET);
  2133.  
  2134.                     copying=1;
  2135.                     copyfile(file2,file1,arcpos0+1,0,0);
  2136.                     stclosearc(file1);
  2137.                     copying=0;
  2138.  
  2139.                     close(file2);
  2140.                     unlink(backup2);
  2141.                 }
  2142.                 else
  2143.                 {
  2144.                     stclosearc(file2);
  2145.                     rename(backup2,arcname);
  2146.                 }
  2147.             }
  2148.         }
  2149.         else
  2150.         {
  2151.             close(file2);
  2152.             if (!Device)
  2153.                 unlink(backup2);
  2154.         }
  2155.     }
  2156.     else
  2157.     {
  2158.         close(file2);
  2159.         if (!Device)
  2160.         {
  2161.             unlink(backup2);
  2162.             rename(backup1,arcname);
  2163.         }
  2164.     }
  2165.     file1=file2=NULL;
  2166. }
  2167.  
  2168. void append(void)
  2169. {
  2170.     register int cnt;
  2171.  
  2172.     if (Device)
  2173.         file1=NULL;
  2174.     else if ((file1=fopen(arcname,"rb"))!=NULL)
  2175.     {
  2176.         close(file1);
  2177.         openbackup1();
  2178.     }
  2179.  
  2180.     mklist();
  2181.     if (!Nfile)
  2182.         error(NOFILEERR,NULL,SUCCS);
  2183.  
  2184.     if (flg_u && !flg_n)
  2185.         flg_n++;
  2186.  
  2187.     if (file1)
  2188.         message("Updating archive",arcname);
  2189.     else if (Device)
  2190.         message("Freeze/Store to",arcname);
  2191.     else
  2192.         message("Creating archive",arcname);
  2193.  
  2194.     openbackup2();
  2195.     if (file1)
  2196.         search_lzh(file1,file2,0);
  2197.     else if (flg_z)
  2198.         archive_comment(file2);
  2199.  
  2200.     buffered=0;
  2201.     cnt=execappend();
  2202.     if (buffered)
  2203.     {
  2204.         ShipOut();
  2205.         LSeek(file2,arcpos0,SEEK_SET);
  2206.     }
  2207.  
  2208.     endofupdate(cnt);
  2209.  
  2210.     if (flg_d)
  2211.         delfile();
  2212. }
  2213.  
  2214. void pack_afx(void)
  2215. {
  2216.     register filebuf *f0;
  2217.     register int file=1,tst;
  2218.     register uchar *x;
  2219.  
  2220.     flg_x=3;
  2221.     old_afx=afxonoff(0L);
  2222.  
  2223.     mklist();
  2224.     if (!Nfile)
  2225.         error(NOFILEERR,NULL,SUCCS);
  2226.  
  2227.     FlgMethod=flg_x=0;
  2228.     f0=(filebuf *) fbuf;
  2229.  
  2230.     while ((f0=f0->next)!=NULL)
  2231.     {
  2232.         if ((x=strrchr(get_fname(f0->dir),'.'))!=NULL && (!strcmp(x,".O") || !strcmp(x,".LIB")))
  2233.             obj=SUCCS;
  2234.         else
  2235.             obj=FAULT;
  2236.  
  2237.         if ((tst=test_afx(f0->dir))==0)
  2238.         {
  2239.             if ((file3=e_fopen(f0->dir,buffer_3,"rb",RDERR,FAULT))!=NULL)
  2240.             {
  2241.                 strcpy(backpath(strcpy(backup2,f0->dir)),"__temp__.lzs");
  2242.                 if ((outfile=file2=e_fopen(outfname=backup2,buffer_2,"wb",MKTMPERR,FAULT))!=NULL)
  2243.                 {
  2244.                     arcpos0=buffered=0;
  2245.                     min_len=f0->cluster;
  2246.                     sethdr((uchar *) f0+f0->fpos,f0->attr,&f0->time,&Hdr2,SUCCS);
  2247.                     freeze(f0->dir,f0->attr,file,f0->Case);
  2248.  
  2249.                     if (buffered && !flg_unpacked)
  2250.                         ShipOut();
  2251.     
  2252.                      close(file2);
  2253.                 }
  2254.  
  2255.                 close(file3);
  2256.     
  2257.                  if (!flg_unpacked)
  2258.                 {
  2259.                     unlink(f0->dir);
  2260.                     if (rename(backup2,f0->dir))
  2261.                         error(RENAMEERR,f0->dir,FAULT);
  2262.                 }
  2263.                 else
  2264.                     unlink(backup2);
  2265.             }
  2266.         }
  2267.         else
  2268.         {
  2269.             if (!flg_q)
  2270.             {
  2271.                 printf("(%d/%d): %s\n ",file,Nfile,f0->dir);
  2272.  
  2273.                 switch (tst)
  2274.                 {
  2275.                 case 1:
  2276.                 #if GERMAN
  2277.                     puts("Datei bereits in AFX-Format");
  2278.                 #else
  2279.                     puts("Already in AFX-format");
  2280.                 #endif
  2281.                     break;
  2282.                 case 2:
  2283.                 #if GERMAN
  2284.                     puts("Datei bereits in LHarc-Format");
  2285.                 #else
  2286.                     puts("Already in LHarc-format");
  2287.                 #endif
  2288.                     break;
  2289.                 case 3:
  2290.                 #if GERMAN
  2291.                     puts("Programm-Datei");
  2292.                 #else
  2293.                     puts("Program-file");
  2294.                 #endif
  2295.                     break;
  2296.                 default:
  2297.                 #if GERMAN
  2298.                     puts("Kann Datei nicht lesen");
  2299.                 #else
  2300.                     puts("Read-Error");
  2301.                 #endif
  2302.                 }
  2303.             }
  2304.         }
  2305.         file++;
  2306.     }
  2307.  
  2308.     if (old_afx)
  2309.     {
  2310.         afxonoff(old_afx);
  2311.         old_afx=0;
  2312.     }
  2313. }
  2314.  
  2315. void make_fullpath(uchar *path)
  2316. {
  2317.     register uchar *p=stpcpy(path,basedir);
  2318.  
  2319.     if (flg_x)
  2320.     {
  2321.         if (dosfilename[0]=='\\')
  2322.         {
  2323.             p=path;
  2324.             if (*p && p[1]==':')
  2325.             {
  2326.                 if (__mint && toupper(*p)=='U' && p[2]=='\\' && p[3] && p[4]=='\\')
  2327.                     p+=4;
  2328.                 else
  2329.                     p+=2;
  2330.             }
  2331.         }
  2332.  
  2333.         strcpy(p,dosfilename);
  2334.     }
  2335.     else
  2336.         strcpy(p,get_fname(dosfilename));
  2337. }
  2338.  
  2339. void freshen(void)
  2340. {
  2341.     _DOSTIME time;
  2342.     register uchar path[MAXPATH];
  2343.     register long ok;
  2344.     register int cnt=0,attr;
  2345.  
  2346.     openbackup1();
  2347.     message("Freshening archive",arcname);
  2348.  
  2349.     openbackup2();
  2350.     search_lzh(file1,file2,0);
  2351.     buffered=0;
  2352.  
  2353.     while (gethdr(file1,&Hdr1))
  2354.     {
  2355.         if (!(Hdr1.Attr & FA_DIR) && matchpat(matchfilename,-1,Hdr1.Attr))
  2356.         {
  2357.             make_fullpath(path);
  2358.  
  2359.             if (__mint)
  2360.             {
  2361.                 ok=Fxattr(0,path,(uchar *) &xattr);
  2362.                 time.time=xattr.ctime;
  2363.                 time.date=xattr.cdate;
  2364.                 attr=xattr.attr;
  2365.             }
  2366.             else
  2367.             {
  2368.                 ok=Fsfirst(path,0x07);
  2369.                 time.time=_dta.dta_time;
  2370.                 time.date=_dta.dta_date;
  2371.                 attr=_dta.dta_attribute;
  2372.             }
  2373.  
  2374.             if (!ok && (flg_c || (FTimeToULong(&Hdr1.Ftime)<FTimeToULong(&time))) && (file3=fopen(path,"rb"))!=NULL)
  2375.             {
  2376.                 sethdr(filename,attr,&time,&Hdr2,FAULT);
  2377.                 freeze(path,(oldtos) ? attr^FA_CHANGED : attr,-1,1);
  2378.                 close(file3);
  2379.                 cnt++;
  2380.  
  2381.                 if (flg_d && !(Hdr1.Attr & FA_DIR))
  2382.                     unlink(path);
  2383.  
  2384.                 sseek(file1,nextarcpos,1);
  2385.                 continue;
  2386.             }
  2387.         }
  2388.  
  2389.         copyold(SUCCS);
  2390.     }
  2391.  
  2392.     if (buffered)
  2393.     {
  2394.         ShipOut();
  2395.         LSeek(file2,arcpos0,SEEK_SET);
  2396.     }
  2397.  
  2398.     endofupdate(cnt);
  2399. }
  2400.  
  2401. int Attrib(uchar *p)
  2402. {
  2403.     if (__mint)
  2404.     {
  2405.         if (!Fxattr(0,p,(uchar *) &xattr))
  2406.             return(xattr.attr & FA_DIR);
  2407.     }
  2408.     else if (!Fsfirst(p,-1))
  2409.         return(_dta.dta_attribute & FA_DIR);
  2410.  
  2411.     return(-1);
  2412. }
  2413.  
  2414. int tstdir(uchar *name,int flag)
  2415. {
  2416.     register uchar path[MAXPATH],*p,yn;
  2417.     register int ok;
  2418.  
  2419.     if (!flag && flg_R && stricmp(get_fname(name),get_fname(matchfilename)))
  2420.     {
  2421.         printf("%s (%s):\n%s",name,get_fname(filename),M_ENTERNEW);
  2422.         gets(path);
  2423.  
  2424.         if (path[0]!='\0')
  2425.         {
  2426.             strcpy(backpath(name),get_fname(path));
  2427.             Convert_Filename(name,NULL,0);
  2428.         }
  2429.     }
  2430.  
  2431. Again:
  2432.     if (flag || flg_x)
  2433.     {
  2434.         p=name;
  2435.         if (*p && p[1]==':')
  2436.         {
  2437.             p+=2;
  2438.     
  2439.             if (__mint && toupper(p[-2])=='U' && p[0]=='\\' && p[1] && p[2]=='\\')
  2440.                 p+=2;
  2441.         }
  2442.     
  2443.         if (*p=='\\')
  2444.             p++;
  2445.     
  2446.         if (flag>=0)
  2447.             yn=(flg_m>0 && flg_m<3) ? 'Y' : 'N';
  2448.         else
  2449.             yn='Y';
  2450.     
  2451.         while ((p=strchr(p,'\\'))!=NULL)
  2452.         {
  2453.             memcpy(path,name,p-name);
  2454.             path[p-name]=0;
  2455.     
  2456.             switch(Attrib(path))
  2457.             {
  2458.                 case 0:
  2459.                     error(MKDIRERR,path,(flag<0) ? SUCCS : FAULT);
  2460.                     return(FAULT);
  2461.                 case -1:
  2462.                     if (yn=='N')
  2463.                     {
  2464.                         printf("%s:\n%s",name,M_MKDIR);
  2465.  
  2466.                         if ((yn=get_key("YNA"))=='N')
  2467.                             return(FAULT);
  2468.                         else if (yn=='A')
  2469.                         {
  2470.                             flg_m=(flg_m) ? 1 : 2;
  2471.                             yn='Y';
  2472.                         }
  2473.                     }
  2474.  
  2475.                     if (Dcreate(path))
  2476.                     {
  2477.                         error(MKDIRERR,path,(flag<0) ? SUCCS : FAULT);
  2478.                         return(FAULT);
  2479.                     }
  2480.             }
  2481.  
  2482.             p++;
  2483.         }
  2484.     }
  2485.  
  2486.     if (!flag)
  2487.     {
  2488.         if (__mint)
  2489.         {
  2490.             ok=(int) Fxattr(0,name,&xattr);
  2491.             _dta.dta_attribute=xattr.attr;
  2492.             _dta.dta_date=xattr.cdate;
  2493.             _dta.dta_time=xattr.ctime;
  2494.         }
  2495.         else
  2496.             ok=Fsfirst(name,-1);
  2497.  
  2498.         if (!ok)
  2499.         {
  2500.             if ((_dta.dta_attribute & FA_DIR) && !UnixFile)
  2501.             {
  2502.                 if (!flg_q)
  2503.                     printf("Skipped: %s: Object with same name exists\n",name);
  2504.                 return(FAULT);
  2505.             }
  2506.             else if ((!UnixFile || (flg_m & 0x01)) && !flg_c && (((ulong) _dta.dta_date<<16)|(uint) _dta.dta_time)>=FTimeToULong(&Hdr1.Ftime))
  2507.             {
  2508.                 if (!flg_q)
  2509.                     printf("Skipped: %s: New or same file exists\n",name);
  2510.                 return(FAULT);
  2511.             }
  2512.             else if ((flg_m & 0x01)==0)
  2513.             {
  2514.                 if (UnixFile)
  2515.                     printf("%s (%s):\n%s",name,get_fname(filename),M_OVERWT);
  2516.                 else
  2517.                     printf("%s:\n%s",name,M_OVERWT);
  2518.  
  2519.                 if ((yn=get_key("YNRA"))=='R')
  2520.                 {
  2521.                     printf(M_ENTERNEW);
  2522.                     gets(path);
  2523.  
  2524.                     if (path[0]!='\0')
  2525.                     {
  2526.                         strcpy(backpath(name),get_fname(path));
  2527.                         Convert_Filename(name,NULL,0);
  2528.                         goto Again;
  2529.                     }
  2530.                     else
  2531.                         return(FAULT);
  2532.                 }
  2533.                 else if (yn=='N')
  2534.                     return(FAULT);
  2535.                 else if (yn=='A')
  2536.                     flg_m=(flg_m) ? 1 : 3;
  2537.             }
  2538.  
  2539.             if (_dta.dta_attribute & FA_RDONLY)
  2540.             {
  2541.                 if (_dta.dta_attribute!=Hdr1.Attr)
  2542.                 {
  2543.                     if (!flg_q)
  2544.                         printf("%s: %s\n",name,M_RDONLY);
  2545.                     return(FAULT);
  2546.                 }
  2547.                 else
  2548.                     Fattrib(name,1,_dta.dta_attribute ^ FA_RDONLY);
  2549.             }
  2550.         }
  2551.     }
  2552.  
  2553.     return(SUCCS);
  2554. }
  2555.  
  2556. int tstID(uchar *h)
  2557. {
  2558.     static uchar IDpat[7][6]={"lz4","lz5","lh0","lh1","lh5","afx","lhd"};
  2559.  
  2560.     if (h[0]!='-' || h[4]!='-')
  2561.         return(-1);
  2562.     else
  2563.     {
  2564.         register int m=6;
  2565.  
  2566.         strlwr(++h);
  2567.         while (m>=0 && memcmp(h,IDpat[m],3))
  2568.             m--;
  2569.  
  2570.         return((m==5) ? 1 : m);
  2571.     }
  2572. }
  2573.  
  2574. uchar *Trunc1File(uchar *s,uchar *d)
  2575. {
  2576.     register int l=(int) strlen(s);
  2577.     register uchar c,*t;
  2578.  
  2579.     if (fn_name<=12)
  2580.     {
  2581.         register i,j,k,m;
  2582.  
  2583.         for (i=l;--i>=0;)
  2584.             if (s[i]=='.')
  2585.                 break;
  2586.  
  2587.         if (i<0)
  2588.             m=l;
  2589.         else
  2590.             m=i;
  2591.  
  2592.         t=s;
  2593.         for (j=k=0,t=s;j<=7;j++)
  2594.         {
  2595.             c=*t++;
  2596.             if ((i>0 && k++>i) || c=='\0' || j>=m)
  2597.                 break;
  2598.  
  2599.             if (c>32 && c!='.' && c!=':' && c!='*' && c!='?')
  2600.                 *d++=c;
  2601.             else
  2602.                 j--;
  2603.         }
  2604.  
  2605.         if (i>=0 && fn_name==12)
  2606.         {
  2607.             for (j=4;--j>=0;)
  2608.             {
  2609.                 if ((c=s[i++])=='\0')
  2610.                     break;
  2611.                 if (c>32 && c!=':' && c!='*' && c!='?')
  2612.                     *d++=c;
  2613.             }
  2614.         }
  2615.     }
  2616.     else
  2617.     {
  2618.         strcpy(d,s);
  2619.  
  2620.         if (l<=fn_name)
  2621.             d+=l;
  2622.         else if ((t=strrchr(s,'.'))!=NULL && t>s)
  2623.         {
  2624.             l-=(int) (t-s);
  2625.             l=fn_name-l;
  2626.             if (d[l-1]=='.')
  2627.                 l--;
  2628.  
  2629.             strcpy(d+l,t);
  2630.             d+=fn_name;
  2631.         }
  2632.         else
  2633.             d+=fn_name;
  2634.     }
  2635.  
  2636.     *d='\0';
  2637.     return(d);
  2638. }
  2639.  
  2640. void TruncFile(uchar *s)
  2641. {
  2642.     uchar file[MAXPATH],dest[MAXPATH];
  2643.     register uchar *f=file,*d=dest,*s1=s,c;
  2644.  
  2645.     *d='\0';
  2646.     while ((c=*s++)!='\0')
  2647.     {
  2648.         if (c=='\\' || c==':')
  2649.         {
  2650.             *d='\0';
  2651.             f=Trunc1File(dest,f);
  2652.             *f++=c;
  2653.             *f='\0';
  2654.             d=dest;
  2655.         }
  2656.         else
  2657.             *d++=c;
  2658.     }
  2659.  
  2660.     *d='\0';
  2661.     f=Trunc1File(dest,f);
  2662.     strcpy(s1,file);
  2663. }
  2664.  
  2665. int extract(void)
  2666. {
  2667.     register uchar *p,*q;
  2668.     register int m,cnt=0,succs;
  2669.  
  2670.     if (cmd=='P')
  2671.     {
  2672.         if (pager)
  2673.             message("Extract from",arcname);
  2674.         if (flg_v<2)
  2675.             fprintf(file3,"Extract from: %s\n",arcname);
  2676.     }
  2677.     else
  2678.         message("Extract from",arcname);
  2679.  
  2680.     if (all && exno==0)
  2681.         flg_d=0;
  2682.  
  2683.     if (flg_d)
  2684.     {
  2685.         flg_z=0;
  2686.         openbackup1();
  2687.         openbackup2();
  2688.         if (search_lzh(file1,file2,1)==FAULT)
  2689.         {
  2690.             close(file1);
  2691.             close(file2);
  2692.             unlink(backup2);
  2693.             rename(backup1,arcname);
  2694.             return(0);
  2695.         }
  2696.     }
  2697.     else if (openarc1(bsize)==FAULT)
  2698.         return(0);
  2699.  
  2700.     infile=file1;
  2701.  
  2702.     while (gethdr(file1,&Hdr1))
  2703.     {
  2704.         succs=FAULT;
  2705.         if (matchpat(matchfilename,-1,Hdr1.Attr))
  2706.         {
  2707.             if (cmd=='E')
  2708.                 make_fullpath(pathname);
  2709.  
  2710.             if ((m=tstID(Hdr1.HeadID))<0)
  2711.             {
  2712.                 if (!flg_q)
  2713.                     printf("Skipped: %s: Unknown method\n",filename);
  2714.                 skipped++;
  2715.             }
  2716.             else if (cmd=='E' && maxlen>0 && Hdr1.OrgSiz>maxlen)
  2717.             {
  2718.                 if (!flg_q)
  2719.                     printf("Skipped: %s: File too long\n",filename);
  2720.                 skipped++;
  2721.             }
  2722.             else if (cmd=='E' && !flg_a && (Hdr1.Attr & (FA_HIDDEN|FA_SYSTEM)))
  2723.             {
  2724.                 if (!flg_q)
  2725.                     printf("Skipped: %s: Hidden/System File\n",filename);
  2726.                 skipped++;
  2727.             }
  2728.             else if (Hdr1.Attr & FA_DIR)
  2729.             {
  2730.                 if (cmd=='E')
  2731.                 {
  2732.                     if (!flg_q)
  2733.                     {
  2734.                         if (UnixFile)
  2735.                             printf("%s (%s): Directory\n",pathname,filename);
  2736.                         else
  2737.                             printf("%s: Directory\n",pathname);
  2738.  
  2739.                         if (*comment && flg_x)
  2740.                             puts(comment);
  2741.                     }
  2742.  
  2743.                     if ((succs=tstdir(strcat(pathname,"\\"),1))!=0)
  2744.                     {
  2745.                         if (!flg_q)
  2746.                         {
  2747.                             switch(flg_n)
  2748.                             {
  2749.                             case 0:
  2750.                                 printf(" Melted   :    %c\n",star);
  2751.                                 break;
  2752.                             case 2:
  2753.                                 puts(" Melted  : 100%%");
  2754.                                 break;
  2755.                             case 3:
  2756.                                 puts(" Melted  :   -");
  2757.                             }
  2758.                         }
  2759.  
  2760.                         if (flg_d)
  2761.                             message("Deleting",filename);
  2762.                     }
  2763.                 }
  2764.                 else if (!flg_q)
  2765.                     printf("Skipped: %s: Directory\n",filename);
  2766.             }
  2767.             else if (cmd!='E' || tstdir(pathname,0))
  2768.             {
  2769.                 textsize=Hdr1.OrgSiz;
  2770.                 codesize=Hdr1.PacSiz;
  2771.  
  2772.                 cnt++;
  2773.                 crc=0;
  2774.  
  2775.                 p="Melting ";
  2776.                 q="Melted ";
  2777.  
  2778.                 switch(cmd)
  2779.                 {
  2780.                 case 'E':
  2781.                     if (!flg_q)
  2782.                     {
  2783.                         if (UnixFile)
  2784.                             printf("%s (%s)\n",pathname,filename);
  2785.                         else
  2786.                             puts(pathname);
  2787.                     }
  2788.  
  2789.                     if ((file3=e_fopen(outfname=pathname,buffer_3,"wb",WTERR,FAULT))==NULL)
  2790.                         goto _extract_next;
  2791.                     break;
  2792.                 case 'T':
  2793.                     if (!flg_q)
  2794.                         puts(filename);
  2795.                     file3=NULL;
  2796.                     p="Testing ";
  2797.                     q="Tested ";
  2798.                     break;
  2799.                 case 'P':
  2800.                     if (flg_v<2)
  2801.                         fprintf(file3,"<<< %s >>>\n\n",filename);
  2802.                     if (pager && !flg_q)
  2803.                         puts(filename);
  2804.                 }
  2805.  
  2806.                 if (!flg_q && *comment && flg_x)
  2807.                     puts(comment);
  2808.  
  2809.                 if (file3==stdout)
  2810.                     flg_n=1;
  2811.  
  2812.                 blkdisp(textsize,p,(m==4) ? (N*2) : N);
  2813.                 outfile=file3;
  2814.                 succs=SUCCS;
  2815.  
  2816.                 if (m==3)
  2817.                     Decode();
  2818.                 else if (m==1)
  2819.                     DecodeOld();
  2820.                 else if (m==4)
  2821.                     succs=decode_lh5(textsize,codesize);
  2822.                 else
  2823.                     copyfile(infile,outfile,Hdr1.OrgSiz,1,0);
  2824.  
  2825.                 if (cmd=='E')
  2826.                 {
  2827.                     if (fflush(file3))
  2828.                         error(WTERR,outfname,SUCCS);
  2829.  
  2830.                     if ((!flg_i || flg_i==3) && succs)
  2831.                         Fdatime(&Hdr1.Ftime,file3->_file,1);
  2832.  
  2833.                     if (fclose(file3))
  2834.                         error(WTERR,outfname,SUCCS);
  2835.  
  2836.                     if ((!flg_i || flg_i==2) && succs && (Hdr1.Attr!=FA_CHANGED))
  2837.                         Fattrib(pathname,1,(oldtos) ? (Hdr1.Attr^FA_CHANGED) : Hdr1.Attr);
  2838.  
  2839.                     file3=NULL;
  2840.                 }
  2841.                 else if (cmd=='P' && flg_v<2)
  2842.                     fprintf(file3,"\n");
  2843.  
  2844.                 if (succs)
  2845.                 {
  2846.                     if (has_crc && Hdr1.crc!=crc)
  2847.                     {
  2848.                         errorlevel|=2;
  2849.                         succs=FAULT;
  2850.                         c_err++;
  2851.  
  2852.                         if (!flg_q)
  2853.                         {
  2854.                             if (cmd=='P')
  2855.                                 new_line();
  2856.                         #if GERMAN
  2857.                             puts("\r Prüfsummen-Fehler ");
  2858.                         #else
  2859.                             puts("\r CRC error ");
  2860.                         #endif
  2861.                         }
  2862.                     }
  2863.                     else if (!flg_q && (cmd!='P' || pager))
  2864.                     {
  2865.                         if (flg_n!=1)
  2866.                             printf("\r %s\n",q);
  2867.                         if (flg_d)
  2868.                             message("Deleting",filename);
  2869.                     }
  2870.                 }
  2871.             }
  2872.         }
  2873.  
  2874.         _extract_next:
  2875.         if (succs==FAULT && flg_d)
  2876.             copyold(FAULT);
  2877.         else if (sseek(file1,nextarcpos,0))
  2878.             break;
  2879.     }
  2880.  
  2881.     if (!flg_q && (bad_tab || c_err || skipped || garbage))
  2882.         printf("\nBad Tables:    %d\nCRC errors:    %d\nFiles skipped: %d\nCrashed Files: %d\n",bad_tab,c_err,skipped,garbage);
  2883.  
  2884.     if (flg_d)
  2885.         endofupdate(cnt);
  2886.     else
  2887.         close(file1);
  2888.  
  2889.     return(cnt);
  2890. }
  2891.  
  2892. void delete(void)
  2893. {
  2894.     register int cnt=0;
  2895.  
  2896.     if (!patno)
  2897.         error(NOFNERR,NULL,SUCCS);
  2898.  
  2899.     openbackup1();
  2900.  
  2901.     message("Updating archive",arcname);
  2902.  
  2903.     openbackup2();
  2904.     search_lzh(file1,file2,0);
  2905.  
  2906.     while (gethdr(file1,&Hdr1))
  2907.     {
  2908.         if (matchpat(matchfilename,-1,Hdr1.Attr))
  2909.         {
  2910.             message("Deleting",filename);
  2911.             cnt++;
  2912.             if (sseek(file1,nextarcpos,0))
  2913.                 break;
  2914.         }
  2915.         else
  2916.             copyold(FAULT);
  2917.     }
  2918.  
  2919.     endofupdate(cnt);
  2920. }
  2921.  
  2922. uchar *sysid(void)
  2923. {
  2924.     switch(SystemId)
  2925.     {
  2926.     case 'M':
  2927.         return("MSDOS");
  2928.     case '2':
  2929.         return("OS/2");
  2930.     case '9':
  2931.         return("OS9");
  2932.     case 'K':
  2933.         return("OS/68K");
  2934.     case '3':
  2935.         return("OS/386");
  2936.     case 'H':
  2937.         return("HUMAN");
  2938.     case 'U':
  2939.         return("UNIX");
  2940.     case 'C':
  2941.         return("CP/M");
  2942.     case 'm':
  2943.         return("Mac");
  2944.     case 'R':
  2945.         return("Runser");
  2946.     case 'A':
  2947.         return("Amiga/Atari");
  2948.     case 'a':
  2949.         return("Atari");
  2950.     case 'F':
  2951.         return("FLEX");
  2952.     case 'X':
  2953.         return("XOSK");
  2954.     case 'T':
  2955.         return("TOWNSOS");
  2956.     default:
  2957.         return("");
  2958.     }
  2959. }
  2960.  
  2961. #ifndef __SHELL__
  2962. void list(void)
  2963. {
  2964.     static uchar attr[7]="rhs-da";
  2965.     register uchar buf[79],*p,*b;
  2966.     register ftime *tim=(ftime *) &Hdr1.Ftime;
  2967.     register int i,j,k;
  2968.     register uint rt;
  2969.     ulong Osize,Psize;
  2970.     int Fno,Dno;
  2971.  
  2972.     Osize=Psize=Fno=Dno=0;
  2973.  
  2974. #if GERMAN
  2975.     printf("Inhalt von: %s\n", arcname);
  2976. #else
  2977.     printf("Listing of archive: %s\n", arcname);
  2978. #endif
  2979.  
  2980.     if (openarc1((drive(arcname)<2) ? 8192L : 1024L)==FAULT)
  2981.         return;
  2982.  
  2983.     if (flg_x<3)
  2984.     {
  2985. #if GERMAN
  2986.         puts("\n Name           Original  Gepackt  Rate   Datum    Zeit     Attr Typ   CRC");
  2987. #else
  2988.         puts("\n Name           Original  Packed   Ratio  Date     Time     Attr Type  CRC");
  2989. #endif
  2990.         puts("--------------  --------  -------- ------ -------- -------- ---- ----- ----");
  2991.     }
  2992.     else
  2993.         puts("\n Name\n--------------");
  2994.  
  2995.     while (gethdr(file1,&Hdr1))
  2996.     {
  2997.         if (matchpat(matchfilename,-1,Hdr1.Attr))
  2998.         {
  2999.             if (flg_x<3)
  3000.             {
  3001.                 rt=ratio(Hdr1.PacSiz,Hdr1.OrgSiz);
  3002.                 sprintf(buf, "              %10lu%10lu %3d.%1d%% %2d-%02d-%02d %2d:%02d:%02d ---w       %04X",
  3003.                     Hdr1.OrgSiz, Hdr1.PacSiz, rt / 10, rt % 10,(tim->year + 80) % 100, tim->mon,
  3004.                     tim->day, tim->hour, tim->min, tim->sec * 2,Hdr1.crc);
  3005.                 memcpy(&buf[65],Hdr1.HeadID,5);
  3006.  
  3007.                 for (i=0,j=1;i<6;i++,j<<=1)
  3008.                 {
  3009.                     if (Hdr1.Attr & j)
  3010.                     {
  3011.                         k=attr[i];
  3012.                         if (i<=2)
  3013.                             buf[63-i]=k;
  3014.                         else
  3015.                             buf[60]=k;
  3016.                     }
  3017.                 }
  3018.  
  3019.                 if (flg_x)
  3020.                 {
  3021.                     puts(filename);
  3022.                     p=sysid();
  3023.                     b=buf;
  3024.  
  3025.                     while (*p)
  3026.                         *b++=*p++;
  3027.  
  3028.                     if (flg_x!=2 && *comment)
  3029.                         puts(comment);
  3030.                 }
  3031.                 else
  3032.                 {
  3033.                     register uchar *sl=strrchr(filename,'\\');
  3034.  
  3035.                     if ((Hdr1.Attr & FA_DIR) && sl[1]=='\0')
  3036.                     {
  3037.                         *sl='\0';
  3038.                         p=get_fname(filename);
  3039.                         *sl='\\';
  3040.                     }
  3041.                     else
  3042.                         p=get_fname(filename);
  3043.  
  3044.                     if (p>filename)
  3045.                         buf[0]='+';
  3046.  
  3047.                     if ((i=(int) strlen(p))>15)
  3048.                     {
  3049.                         buf[1]='-';
  3050.                         i=15;
  3051.                     }
  3052.  
  3053.                     memcpy(&buf[2],p,i);
  3054.                 }
  3055.  
  3056.                 puts(buf);
  3057.                 Osize+=Hdr1.OrgSiz;
  3058.                 Psize+=Hdr1.PacSiz;
  3059.             }
  3060.             else
  3061.                 puts(filename);
  3062.  
  3063.             if (Hdr1.Attr & FA_DIR)
  3064.                 Dno++;
  3065.             else
  3066.                 Fno++;
  3067.         }
  3068.  
  3069.         if (sseek(file1,nextarcpos,0))
  3070.             break;
  3071.     }
  3072.  
  3073.     if (Fno || Dno)
  3074.     {
  3075.         if (flg_x<3)
  3076.         {
  3077.             puts("--------------  --------  -------- ------ -------- --------");
  3078.             rt=ratio(Psize, Osize);
  3079.             Fdatime(&arcstamp,file1->_file,0);
  3080.             tim=(ftime *) &arcstamp;
  3081.  
  3082.             printf("  %3d files,  %10lu%10lu %3d.%1d%% %2d-%02d-%02d %2d:%02d:%02d\n  %3d directories\n",
  3083.             Fno, Osize, Psize, rt / 10, rt % 10,(tim->year + 80) % 100, tim->mon,
  3084.             tim->day, tim->hour, tim->min, tim->sec * 2,Dno);
  3085.         }
  3086.         else
  3087.         {
  3088.             puts("--------------");
  3089.         #if GERMAN
  3090.             printf("  %3d Dateien,\n  %3d Ordner\n",Fno,Dno);
  3091.         #else    
  3092.             printf("  %3d files,\n  %3d directories\n",Fno,Dno);
  3093.         #endif
  3094.         }
  3095.     }
  3096.     else
  3097.     #if GERMAN
  3098.         puts("  Keine Datei");
  3099.     #else
  3100.         puts("  no file");
  3101.     #endif
  3102.     close(file1);
  3103. }
  3104. #endif
  3105.  
  3106. void getsw(uchar *p)
  3107. {
  3108.     register uchar s,*q;
  3109.     register int i;
  3110.  
  3111.     while ((s=*p++)!='\0')
  3112.     {
  3113.         q=strchr(swi,s);
  3114.         if (q)
  3115.         {
  3116.             if ((i=(int) (q-swi))<SWI_CNT)
  3117.             {
  3118.                 if (*p=='+')
  3119.                 {
  3120.                     *swipos[i]=1;
  3121.                     p++;
  3122.                 }
  3123.                 else if (*p=='-')
  3124.                 {
  3125.                     *swipos[i]=0;
  3126.                     p++;
  3127.                 }
  3128.                 else if (*p>='0' && *p<='3')
  3129.                     *swipos[i]=*p++ - '0';
  3130.                 else
  3131.                     *swipos[i]=1;
  3132.             }
  3133.  
  3134.             if (flg_q>1)
  3135.             {
  3136.                 new_line();
  3137.                 ptitel++;
  3138.                 flg_q=0;
  3139.             }
  3140.             if (s=='e' || s=='s')
  3141.             {
  3142.                 if (flg_k<=0)
  3143.                 {
  3144.                     flg_k=1;
  3145.                     ex_len=3;
  3146.                 }
  3147.             }
  3148.             else if (s=='r' || s=='X')
  3149.             {
  3150.                 if (!flg_x)
  3151.                     flg_x++;
  3152.             }
  3153.             else if (s=='z')
  3154.             {
  3155.                 if (flg_k<=0)
  3156.                 {
  3157.                     flg_k=1;
  3158.                     ex_len=3;
  3159.                 }
  3160.  
  3161.                 if (*p)
  3162.                 {
  3163.                     com_name=p;
  3164.                     flg_z++;
  3165.                 }
  3166.                 break;
  3167.             }
  3168.             else if (s=='v')
  3169.             {
  3170.                 if (flg_v==3)
  3171.                     flg_q++;
  3172.  
  3173.                 if (*p)
  3174.                 {
  3175.                     if (!flg_v)
  3176.                         flg_v++;
  3177.                     pager=p;
  3178.                 }
  3179.                 break;
  3180.             }
  3181.             else if (s=='M')
  3182.             {
  3183.                 if (isdigit(*p))
  3184.                     maxlen=strtol(p,NULL,10)<<10;
  3185.                 else
  3186.                     maxlen=0;
  3187.                 break;
  3188.             }
  3189.             else if (s=='N')
  3190.             {
  3191.                 for (i=6;--i>=0;)
  3192.                     if (!isdigit(*p++))
  3193.                         break;
  3194.  
  3195.                 if (i<0)
  3196.                 {
  3197.                     flg_N++;
  3198.                     i=(p[-6]-'0')*10 + (p[-5]-'0');
  3199.                     i|=((p[-4]-'0')*10 + (p[-3]-'0'))<<5;
  3200.                     i|=((p[-2]-'0')*10 + (p[-1]-'0') - 80)<<9;
  3201.                     newer.date=i;
  3202.                 }
  3203.                 else
  3204.                 {
  3205.                     flg_N=0;
  3206.                     break;
  3207.                 }
  3208.             }
  3209.             else if (s=='w')
  3210.             {
  3211.                 if (*p)
  3212.                 {
  3213.                     flg_w++;
  3214.                     strcpy(workdir,p);
  3215.                 }
  3216.                 break;
  3217.             }
  3218.             else if (s=='I')
  3219.             {
  3220.                 if (*p)
  3221.                 {
  3222.                     flg_I++;
  3223.                     flg_x=0;
  3224.                     strcpy(incldir,p);
  3225.                 }
  3226.                 break;
  3227.             }
  3228.             else if (s=='U')
  3229.             {
  3230.                 if (*p)
  3231.                 {
  3232.                     flg_U++;
  3233.                     unpack=p;
  3234.                 }
  3235.                 break;
  3236.             }
  3237.             else if (s=='P' && *p)
  3238.             {
  3239.                 star=*p++;
  3240.                 if (*p)
  3241.                     pnt=*p++;
  3242.                 break;
  3243.             }
  3244.             else if (s=='y')
  3245.                 flg_arc++;
  3246.             else if (s=='k')
  3247.             {
  3248.                 if (*p>='0' && *p<='2')
  3249.                     flg_k=*p++ - '0';
  3250.                 else
  3251.                     flg_k=0;
  3252.  
  3253.                 if (!flg_k)
  3254.                     ex_len=flg_e=flg_z=flg_s=0;
  3255.                 else
  3256.                     ex_len=3;
  3257.             }
  3258.             else if (s=='b')
  3259.                 flg_backup++;
  3260.             else if (s=='5')
  3261.             {
  3262.                 flg_5=1;
  3263.                 flg_u=0;
  3264.                 FlgMethod=5;
  3265.             }
  3266.             else if (s=='4')
  3267.             {
  3268.                 flg_5=0;
  3269.                 flg_u=flg_4=1;
  3270.             }
  3271.             else if (s=='l')
  3272.             {
  3273.                 flg_5=flg_u=0;
  3274.                 FlgMethod=0;
  3275.             }
  3276.             else if (s=='o')
  3277.             {
  3278.                 flg_5=flg_u=0;
  3279.                 FlgMethod=1;
  3280.             }
  3281.             else if (s=='u')
  3282.             {
  3283.                 flg_u=1;
  3284.                 flg_5=flg_4=0;
  3285.             }
  3286.         }
  3287.         else if (s=='?')
  3288.         {
  3289.         #ifndef __SHELL__
  3290.             if (!ptitel)
  3291.             {
  3292.                 puts(title_x);
  3293.                 ptitel=1;
  3294.             }
  3295.  
  3296.             puts(use_1);
  3297.             puts(use_2);
  3298.             puts(use_3);
  3299.         #endif
  3300.         }
  3301.         else
  3302.             break;
  3303.     }
  3304.  
  3305.     if (flg_q)
  3306.     {
  3307.         flg_n=flg_m=1;
  3308.         flg_e=flg_z=flg_h=flg_R=0;
  3309.     }
  3310.     else if (i_handle>0)
  3311.     {
  3312.         flg_m=1;
  3313.         flg_R=0;
  3314.     }
  3315. }
  3316.  
  3317. int tstsw(uchar *p)
  3318. {
  3319.     register uchar s,*q;
  3320.     register int i;
  3321.  
  3322.     while ((s=*p++)!='\0')
  3323.     {
  3324.         q=strchr(swi,s);
  3325.         if (q)
  3326.         {
  3327.             if (((int) (q-swi))<SWI_CNT)
  3328.                 if (*p=='+' || *p=='-' || (*p>='0' && *p<='3'))
  3329.                     p++;
  3330.  
  3331.             switch (s)
  3332.             {
  3333.             case 'w':
  3334.             case 'z':
  3335.             case 'U':
  3336.             case 'I':
  3337.             case 'v':
  3338.                 return(SUCCS);
  3339.             case 'M':
  3340.                 return(isdigit(*p));
  3341.             case 'N':
  3342.                 for (i=6;--i>=0;)
  3343.                     if (!isdigit(*p++))
  3344.                         return(FAULT);
  3345.                 break;
  3346.             case 'P':
  3347.                 if (*p)
  3348.                     p++;
  3349.                 if (*p)
  3350.                     p++;
  3351.                 return((*p!='\0') ? FAULT : SUCCS);
  3352.             case 'k':
  3353.                 if (*p>='0' && *p<='2')
  3354.                     p++;
  3355.             }
  3356.         }
  3357.         else if (s!='?')
  3358.             return(FAULT);
  3359.     }
  3360.  
  3361.     return(SUCCS);
  3362. }
  3363.  
  3364. void executecmd(void)
  3365. {
  3366.     register int cnt;
  3367.  
  3368.     INIT_TIMER;
  3369.  
  3370.     switch(cmd)
  3371.     {
  3372.     case 'M':
  3373.         flg_d=1;
  3374.     case 'A':
  3375.         flg_c++;
  3376.     case 'U':
  3377.         flg_chk=0;
  3378.         if (cmd=='U')
  3379.             flg_A=0;
  3380.         append();
  3381.         break;
  3382.     case 'C':
  3383.         flg_X=flg_f=flg_e=flg_z=flg_d=flg_backup=flg_u=flg_4=flg_5=flg_I=0;
  3384.         if (flg_k==2)
  3385.             flg_k=ex_len=0;
  3386.         pack_afx();
  3387.         break;
  3388.     case 'R':
  3389.     case 'F':
  3390.         flg_chk=flg_f=0;
  3391.         freshen();
  3392.         break;
  3393.     case 'P':
  3394.         if (pager==NULL)
  3395.         {
  3396.             file3=stdout;
  3397.             extract();
  3398.         }
  3399.         else
  3400.         {
  3401.             if (flg_w)
  3402.                 strcpy(pathname,workdir);
  3403.             else
  3404.                 backpath(strcpy(pathname,arcname));
  3405.             get_tempname(pathname);
  3406.  
  3407.             file3=e_fopen(outfname=pathname,buffer_3,"wb",MKTMPERR,SUCCS);
  3408.             cnt=extract();
  3409.             if (fclose(file3))
  3410.                 error(WTERR,outfname,SUCCS);
  3411.             file3=NULL;
  3412.             
  3413.             if (cnt)
  3414.             {
  3415.                 uchar buffer[127]="*";
  3416.                 strncat(buffer,pathname,125);
  3417.                 Pexec(0,pager,buffer,NULL);
  3418.             }
  3419.  
  3420.             unlink(pathname);
  3421.         }
  3422.         break;
  3423.     case 'X':
  3424.         cmd='E';
  3425.     case 'T':
  3426.     case 'E':
  3427.         flg_v=flg_z=0;
  3428.         extract();
  3429.         break;
  3430. #ifndef __SHELL__
  3431.     case 'V':
  3432.         if (!flg_x)
  3433.             flg_x++;
  3434.     case 'L':
  3435.         flg_chk=0;
  3436.         list();
  3437.         break;
  3438. #endif
  3439.     case 'D':
  3440.         flg_chk=0;
  3441.         if (!flg_f)
  3442.             flg_f=2;
  3443.         delete();
  3444. #ifndef __SHELL__
  3445.         break;
  3446.     case 'S':
  3447.         if (!flg_q)
  3448.             puts("Self-Extracting-Files: NOT YET IMPLEMENTED !\7");
  3449.         errorlevel|=64;
  3450.         lha_exit();
  3451. #endif
  3452.     }
  3453.  
  3454.     EXIT_TIMER;
  3455.     if (!flg_q)
  3456.         new_line();
  3457. }
  3458.  
  3459. void OneNewFile(uchar *p)
  3460. {
  3461.     register uchar *s;
  3462.     register int len;
  3463.  
  3464.     if ((s=strpbrk(p,"\n"))!=NULL)
  3465.         *s='\0';
  3466.  
  3467.     if ((len=(int) strlen(p)-1)<0)
  3468.         return;
  3469.  
  3470.     if (!patno && !basedir[0] && !cmdlist && (p[len]=='\\' || p[len]==':'))
  3471.         slash(strcpy(basedir,p),1);
  3472.     else if (*p!=EXCLUDE && *p!='~')
  3473.     {
  3474.         if (patno>=MAX_PAT || (fileptr-fileregbuf+strlen(get_fname(p)))>=(FILEBUFSIZ-1))
  3475.             message(M_FILETAB,p);
  3476.         else
  3477.         {
  3478.             travel_file[patno]=travel_rel[patno]=0;
  3479.  
  3480.             while (((s=strstr(p,"\\;"))!=NULL || (s=strstr(p,";\\"))!=NULL))
  3481.             {
  3482.                 if (*s=='\\')
  3483.                     s++;
  3484.                 strcpy(s,s+1);
  3485.                 if (*s=='\\')
  3486.                     s++;
  3487.                 travel_rel[patno]=s-p;
  3488.             }
  3489.  
  3490.             strcpy(fileptr,s=get_fname(p));
  3491.             *s='\0';
  3492.  
  3493.             if (*fileptr=='\0')
  3494.             {
  3495.                 travel_wild[patno]=SUCCS;
  3496.  
  3497.                 if (slash(p,-1))
  3498.                 {
  3499.                     register uchar path[MAXPATH];
  3500.  
  3501.                     slash(strcpy(path,p),1);
  3502.                     if ((p=strdup(path))==NULL)
  3503.                         error(MEMOVRERR,NULL,SUCCS);
  3504.                 }
  3505.             }
  3506.             else if (patno>0 && travel_rel[patno]==travel_rel[patno-1] && !strcmp(p,travel_path[patno-1]))
  3507.             {
  3508.                 if (travel_file[patno-1]>0)
  3509.                 {
  3510.                     travel_wild[patno-1]|=wildcard(fileptr);
  3511.                     fileptr[-1]=',';
  3512.                     while (*fileptr++);
  3513.                 }
  3514.                 return;
  3515.             }
  3516.             else
  3517.             {
  3518.                 travel_file[patno]=(int) (fileptr-fileregbuf);
  3519.                 travel_wild[patno]=wildcard(fileptr);
  3520.                 while (*fileptr++);
  3521.             }
  3522.  
  3523.             travel_path[patno]=p;
  3524.             travel_len[patno++]=(int) strlen(p);
  3525.         }
  3526.     }
  3527.     else if (*++p!='\0')
  3528.     {
  3529.         if (exno>=MAX_EXCLD)
  3530.             message(M_FILETAB,p);
  3531.         else
  3532.             exclude_file[exno++]=get_fname(p);
  3533.     }
  3534. }
  3535.  
  3536. void newfile(uchar *p)
  3537. {
  3538.     if (*p=='&' || *p==FILE_LIST)
  3539.     {
  3540.         register FILE *f;
  3541.  
  3542.         if (p[1]=='-' && p[2]=='\0')
  3543.             f=stdin;
  3544.         else
  3545.             f=fopen(p+1,"r");
  3546.  
  3547.         if (f!=NULL)
  3548.         {
  3549.             register uchar file[MAXPATH],*space;
  3550.  
  3551.             if (f==stdin)
  3552.                 puts(M_PATH);
  3553.  
  3554.             while (fgets(file,MAXPATH-1,f))
  3555.             {
  3556.                 space=file;
  3557.                 while (*space==' ')
  3558.                     space++;
  3559.                 strcpy(file,space);
  3560.  
  3561.                 space=strchr(file,' ');
  3562.                 if (space)
  3563.                     *space=0;
  3564.  
  3565.                 Convert_Filename(file,NULL,-1);
  3566.                 if (file[0]=='&')
  3567.                 {
  3568.                     if (strcmp("&-",file))
  3569.                         newfile(file);
  3570.                 }
  3571.                 else if (file[0]!='\r' && file[0]!='\n')
  3572.                 {
  3573.                     if ((space=strdup(file))==NULL)
  3574.                         error(MEMOVRERR,NULL,SUCCS);
  3575.                     OneNewFile(space);
  3576.                 }
  3577.                 else if (f==stdin)
  3578.                     break;
  3579.             }
  3580.  
  3581.             if (f!=stdin)
  3582.                 close(f);
  3583.         }
  3584.     }
  3585.     else
  3586.         OneNewFile(p);
  3587. }
  3588.  
  3589. void copyfile(FILE *Source,FILE *Dest,long size,int crcflg,int bufflg)
  3590. {
  3591.     register long n,block;
  3592.  
  3593.     if (bufflg)
  3594.         Dest=NULL;
  3595.  
  3596.     if (crcflg)
  3597.         crc=0;
  3598.  
  3599.     if (!crcflg || blocksize>bsize || flg_n==1)
  3600.         block=bsize;
  3601.     else
  3602.         block=blocksize;
  3603.  
  3604.     while (size>0)
  3605.     {
  3606.         n=block>size ? size : block;
  3607.         if (fread((bufflg) ? outrec.ptr : buffer_gen,n,1,Source)!=1)
  3608.             error(RDERR,infname,SUCCS);
  3609.  
  3610.         if (crcflg)
  3611.         {
  3612.             if (!flg_chk)
  3613.                 block_crc(n,(bufflg) ? outrec.ptr : buffer_gen);
  3614.             ProcInd();
  3615.         }
  3616.  
  3617.         if (Dest && fwrite(buffer_gen,n,1,Dest)!=1)
  3618.             error(WTERR,outfname,SUCCS);
  3619.  
  3620.         if (bufflg)
  3621.         {
  3622.             outrec.ptr+=n;
  3623.             outrec.cnt-=n;
  3624.         }
  3625.  
  3626.         size-=n;
  3627.     }
  3628.  
  3629.     if (ferror(Source))
  3630.         error(RDERR,infname,SUCCS);
  3631. }
  3632.  
  3633. void EncodeOld(void)
  3634. {
  3635.     register uchar code_buf[34],*code=code_buf,*ptr,*tbuf=text_buf;
  3636.     register int i,r,s=0,m=N-1,c,last_match_length;
  3637.     ulong printcount;
  3638.     uchar mask=1;
  3639.     int    len;
  3640.  
  3641.     printcount=textsize=0;
  3642.     InitTree();
  3643.  
  3644.     *code++=0;
  3645.     for (i=r=(N-F),ptr=tbuf;--i>=0;)
  3646.         *ptr++=' ';
  3647.  
  3648.     for (i=0;i<F && (c=crc_getc(infile))!=EOF;i++)
  3649.         *ptr++=c;
  3650.  
  3651.     textsize=(len=i);
  3652.     if (!textsize)
  3653.         return;
  3654.  
  3655.     for (i=1;i<=F;i++)
  3656.         InsertONode(r - i);
  3657.     InsertONode(r);
  3658.  
  3659.     do
  3660.     {
  3661.         if (match_length>len)
  3662.             match_length=len;
  3663.  
  3664.         if (match_length <=THRESHOLD)
  3665.         {
  3666.             match_length=1;
  3667.             code_buf[0]|=mask;
  3668.             *code++=tbuf[r];
  3669.         }
  3670.         else
  3671.         {
  3672.             *code++=(uchar) match_position;
  3673.             *code++=(uchar) (((match_position >> 4) & 0xf0) | (match_length - (THRESHOLD + 1)));
  3674.         }
  3675.  
  3676.         if (!(mask<<=1))
  3677.         {
  3678.             i=(int) (code - code_buf);
  3679.             ptr=(code=code_buf);
  3680.  
  3681.             while (--i>=0)
  3682.                 buf_putc(*ptr++);
  3683.  
  3684.             *code++=0;
  3685.             mask=1;
  3686.         }
  3687.  
  3688.         last_match_length=match_length;
  3689.         for (i=0;i<last_match_length && (c=crc_getc(infile))!=EOF;i++)
  3690.         {
  3691.             DeleteONode(s);
  3692.             tbuf[s]=c;
  3693.             if (s < F - 1)
  3694.                 tbuf[s + N]=c;
  3695.             s=(++s) & m;
  3696.             r=(++r) & m;
  3697.             InsertONode(r);
  3698.         }
  3699.  
  3700.         if ((textsize+=i)>printcount)
  3701.         {
  3702.             ProcInd();
  3703.             printcount+=blocksize;
  3704.         }
  3705.  
  3706.         while (i<last_match_length)
  3707.         {
  3708.             DeleteONode(s);
  3709.             s=(++s) & m;
  3710.             r=(++r) & m;
  3711.             if (--len)
  3712.                 InsertONode(r);
  3713.             i++;
  3714.         }
  3715.     } while (len>0);
  3716.  
  3717.     if ((i=(int) (code - code_buf))>1)
  3718.     {
  3719.         ptr=code_buf;
  3720.         while (--i>=0)
  3721.             buf_putc(*ptr++);
  3722.     }
  3723.  
  3724.     if (!buffered)
  3725.         shipout();
  3726. }
  3727.  
  3728. void DecodeOld(void)
  3729. {
  3730.     register int i,k,r=N-F,c=0x2020,m=N-1,*tbuf=(int *) text_buf;
  3731.     register uint crcr=crc;
  3732.     long todo=codesize,done=blocksize;
  3733.     uint flags=0;
  3734.  
  3735.     if (outfile)
  3736.         OpenOut();
  3737.     for (k=(N-F)>>1;--k>=0;)
  3738.         *tbuf++=c;
  3739.  
  3740.     for (;;)
  3741.     {
  3742.         if (!((flags>>=1) & 256))
  3743.         {
  3744.             c=Bgetc(infile);
  3745.             if (todo--==0)
  3746.                 break;
  3747.             flags=c|0xff00;
  3748.         }
  3749.  
  3750.         if (todo--==0)
  3751.             break;
  3752.  
  3753.         if (flags & 1)
  3754.         {
  3755.             c=Bgetc(infile);
  3756.             if (outfile)
  3757.                 buf_putc(c);
  3758.             set_crc(crcr,c);
  3759.  
  3760.             text_buf[r++]=c;
  3761.             r&=m;
  3762.  
  3763.             if (done--==0)
  3764.             {
  3765.                 ProcInd();
  3766.                 done=blocksize;
  3767.             }
  3768.         }
  3769.         else
  3770.         {
  3771.             i=Bgetc(infile);
  3772.             if (todo--==0)
  3773.                 break;
  3774.  
  3775.             i|=(((k=Bgetc(infile)) & 0xf0)<<4);
  3776.             k=(k & 0x0f) + (THRESHOLD+1);
  3777.  
  3778.             for (;--k>=0;i++)
  3779.             {
  3780.                 c=text_buf[i & m];
  3781.                 if (outfile)
  3782.                     buf_putc(c);
  3783.                 set_crc(crcr,c);
  3784.  
  3785.                 text_buf[r++]=c;
  3786.                 r&=m;
  3787.  
  3788.                 if (done--==0)
  3789.                 {
  3790.                     ProcInd();
  3791.                     done=blocksize;
  3792.                 }
  3793.             }
  3794.         }
  3795.     }
  3796.  
  3797.     if (outfile)
  3798.         shipout();
  3799.     ProcInd();
  3800.     crc=crcr;
  3801. }
  3802.  
  3803. int fread_crc(uchar *p,int n,FILE *f)
  3804. {
  3805.     n=(int) fread(p,1,n,f);
  3806.     if (ferror(f))
  3807.         error(RDERR,infname,SUCCS);
  3808.     block_crc(n,p);
  3809.     return(n);
  3810. }
  3811.  
  3812. void count_t_freq(void)
  3813. {
  3814.     register int i,k,n;
  3815.     register ushort *tfreq,tf0,tf1;
  3816.     register uchar *clen;
  3817.  
  3818.     for (i=NT,tfreq=t_freq,k=0;--i>=0;)
  3819.         *tfreq++=k;
  3820.  
  3821.     clen=&c_len[n=NC];
  3822.     while (*--clen==0 && --n>=0);
  3823.  
  3824.     i=tf0=tf1=0;
  3825.     clen=c_len;
  3826.     tfreq=t_freq;
  3827.  
  3828.     while (i<n)
  3829.     {
  3830.         i++;
  3831.         if ((k=*clen++)==0)
  3832.         {
  3833.             k=1;
  3834.             while (i<n && *clen==0)
  3835.             {
  3836.                 clen++;
  3837.                 k++;
  3838.                 i++;
  3839.             }
  3840.  
  3841.             if (k<=2)
  3842.                 tf0+=k;
  3843.             else if (k<=18)
  3844.                 tf1++;
  3845.             else if (k==19)
  3846.             {
  3847.                 tf0++;
  3848.                 tf1++;
  3849.             }
  3850.             else
  3851.                 tfreq[2]++;
  3852.         }
  3853.         else
  3854.             tfreq[k+2]++;
  3855.     }
  3856.  
  3857.     tfreq[0]+=tf0;
  3858.     tfreq[1]+=tf1;
  3859. }
  3860.  
  3861. void write_pt_len(register int n,int nbit,register int i_special)
  3862. {
  3863.     register uchar *ptlen;
  3864.     register int i,k,c=3;
  3865.  
  3866.     ptlen=&pt_len[n];
  3867.     while (*--ptlen==0 && --n>=0);
  3868.  
  3869.     putbits(nbit,n);
  3870.  
  3871.     i=0;
  3872.     ptlen=pt_len;
  3873.     while (i<n)
  3874.     {
  3875.         i++;
  3876.         if ((k=*ptlen++)<=6)
  3877.             putbits(3,k);
  3878.         else
  3879.         {
  3880.             k-=c;
  3881.             putbits(k,(1U<<k)-2);
  3882.         }
  3883.  
  3884.         if (i==i_special)
  3885.         {
  3886.             while (i<6 && *ptlen==0)
  3887.             {
  3888.                 ptlen++;
  3889.                 i++;
  3890.             }
  3891.  
  3892.             putbits(2,(i-c) & c);
  3893.         }
  3894.     }
  3895. }
  3896.  
  3897. void write_c_len(void)
  3898. {
  3899.     register int i,k,n;
  3900.     register uchar l0=pt_len[0],*clen;
  3901.     register ushort c0=pt_code[0],c1=pt_code[1];
  3902.  
  3903.     clen=&c_len[n=NC];
  3904.     while (*--clen==0 && --n>=0);
  3905.  
  3906.     putbits(CBIT,n);
  3907.  
  3908.     i=0;
  3909.     clen=c_len;
  3910.     while (i<n)
  3911.     {
  3912.         i++;
  3913.         if ((k=*clen++)==0)
  3914.         {
  3915.             k=1;
  3916.             while (i<n && *clen==0)
  3917.             {
  3918.                 clen++;
  3919.                 k++;
  3920.                 i++;
  3921.             }
  3922.  
  3923.             switch (k)
  3924.             {
  3925.             case 2:
  3926.                 putbits(l0,c0);
  3927.             case 1:
  3928.                 putbits(l0,c0);
  3929.                 break;
  3930.             case 19:
  3931.                 putbits(l0,c0);
  3932.                 putbits(pt_len[1],c1);
  3933.                 putbits(4,15);
  3934.                 break;
  3935.             default:
  3936.                 if (k<=18)
  3937.                 {
  3938.                     putbits(pt_len[1],c1);
  3939.                     putbits(4,k-3);
  3940.                 }
  3941.                 else
  3942.                 {
  3943.                     putbits(pt_len[2],pt_code[2]);
  3944.                     putbits(CBIT,k-20);
  3945.                 }
  3946.             }
  3947.         }
  3948.         else
  3949.             putbits(pt_len[k+2],pt_code[k+2]);
  3950.     }
  3951. }
  3952.  
  3953. void start_huf(void)
  3954. {
  3955.     register ushort *p,v=0;
  3956.     register int i;
  3957.  
  3958.     text_buf[0]=v;
  3959.     for (i=NC,p=c_freq;--i>=0;)
  3960.         *p++=v;
  3961.  
  3962.     for (i=NP,p=p_freq; --i>=0;)
  3963.         *p++=v;
  3964.  
  3965.     subbitbuf=v;
  3966.     bitcount=CHAR_BIT;
  3967. }
  3968.  
  3969. void end_huf(void)
  3970. {
  3971.     send_block();
  3972.     putbits(CHAR_BIT-1,0);
  3973. }
  3974.  
  3975. int read_pt_len(int nn,int nbit,int i_special)
  3976. {
  3977.     register uchar *ptlen=pt_len;
  3978.     register int n;
  3979.  
  3980.     if ((n=getbits(nbit))==0)
  3981.     {
  3982.         register ushort *table=pt_table,c;
  3983.  
  3984.         for (n=nn,c=0;--n>=0;)
  3985.             *ptlen++=c;
  3986.         for (n=256,c=getbits(nbit);--n>=0;)
  3987.             *table++=c;
  3988.     }
  3989.     else
  3990.     {
  3991.         register int c,i=0;
  3992.         register uint mask,bibu;
  3993.  
  3994.         while (i<n)
  3995.         {
  3996.             bibu=bitbuf;
  3997.             if ((c=bibu>>13)==7)
  3998.             {
  3999.                 mask=1U<<12;
  4000.                 while (mask&bibu)
  4001.                 {
  4002.                     mask>>=1;
  4003.                     c++;
  4004.                 }
  4005.             }
  4006.  
  4007.             fillbuf((c<7) ? 3 : c-3);
  4008.             *ptlen++=c;
  4009.  
  4010.             i++;
  4011.             if (i==i_special)
  4012.             {
  4013.                 i+=(c=getbits(2));
  4014.                 mask=0;
  4015.                 while (--c>=0)
  4016.                     *ptlen++=mask;
  4017.             }
  4018.         }
  4019.  
  4020.         c=0;
  4021.         n=nn;
  4022.         while (i<n)
  4023.         {
  4024.             *ptlen++=c;
  4025.             i++;
  4026.         }
  4027.  
  4028.         if (!make_table(n,pt_len,8,pt_table))
  4029.             return(FAULT);
  4030.     }
  4031.  
  4032.     return(SUCCS);
  4033. }
  4034.  
  4035. int read_c_len(void)
  4036. {
  4037.     register uchar *clen=c_len;
  4038.     register int n,i;
  4039.  
  4040.     if ((n=getbits(CBIT))==0)
  4041.     {
  4042.         register ulong *daddy=(ulong *) dad,k;
  4043.  
  4044.         for (i=(NC>>1),k=0;--i>=0;*((int *) clen)++=(int) k);
  4045.         k=getbits(CBIT);
  4046.         k=(k<<16)|k;
  4047.         for (i=2048;--i>=0;*daddy++=k);
  4048.     }
  4049.     else
  4050.     {
  4051.         register ushort *pttable=pt_table;
  4052.         register uint mask,bibu;
  4053.         register int c;
  4054.  
  4055.         i=0;
  4056.         while (i<n)
  4057.         {
  4058.             bibu=bitbuf;
  4059.             c=pttable[bibu>>8];
  4060.             if (c>=NT)
  4061.             {
  4062.                 mask=1U<<7;
  4063.                 do
  4064.                 {
  4065.                     if (bibu&mask)
  4066.                         c=right[c];
  4067.                     else
  4068.                         c=left[c];
  4069.                     mask>>=1;
  4070.                 } while (c>=NT);
  4071.             }
  4072.  
  4073.             fillbuf(pt_len[c]);
  4074.             if (c>2)
  4075.             {
  4076.                 *clen++=(c-2);
  4077.                 i++;
  4078.             }
  4079.             else if (c)
  4080.             {
  4081.                 if (--c==0)
  4082.                     c=getbits(4)+3;
  4083.                 else
  4084.                     c=getbits(CBIT)+20;
  4085.                 i+=c;
  4086.                 mask=0;
  4087.                 while (--c>=0)
  4088.                     *clen++=mask;
  4089.             }
  4090.             else
  4091.             {
  4092.                 *clen++=c;
  4093.                 i++;
  4094.             }
  4095.         }
  4096.  
  4097.         mask=0;
  4098.         bibu=NC;
  4099.         while (i<bibu)
  4100.         {
  4101.             *clen++=mask;
  4102.             i++;
  4103.         }
  4104.  
  4105.         if (!make_table(NC,c_len,12,(ushort *) dad))
  4106.             return(FAULT);
  4107.     }
  4108.  
  4109.     return(SUCCS);
  4110. }
  4111.  
  4112. void make_len(int root)
  4113. {
  4114.     register int i,k;
  4115.     register uint cum=0;
  4116.     register ushort *lencnt=len_cnt,*spt=sortptr;
  4117.  
  4118.     for (i=17;--i>=0;)
  4119.         *lencnt++=cum;
  4120.  
  4121.     count_len(root);
  4122.     for (i=17,k=0,lencnt=&len_cnt[17];--i>=0;)
  4123.         cum+=(*--lencnt)<<(k++);
  4124.  
  4125.     while (cum!=(1U<<16))
  4126.     {
  4127.         len_cnt[16]--;
  4128.  
  4129.         for (i=17,lencnt=&len_cnt[17];--i>=0;)
  4130.             if (*--lencnt)
  4131.             {
  4132.                 lencnt[0]--;
  4133.                 lencnt[1]+=2;
  4134.                 break;
  4135.             }
  4136.         cum--;
  4137.     }
  4138.  
  4139.     for (i=17,lencnt=&len_cnt[17];--i>=0;)
  4140.     {
  4141.         k=*--lencnt;
  4142.         while (--k>=0)
  4143.             len[*spt++]=i;
  4144.     }
  4145.  
  4146.     sortptr=spt;
  4147. }
  4148.  
  4149. #ifdef __SHELL__
  4150. #define print_title(a)
  4151. #else
  4152. void print_title(uchar **argv)
  4153. {
  4154.     if (!flg_q)
  4155.     {
  4156.         #if BETA==0
  4157.         register uchar *env;
  4158.         #endif
  4159.  
  4160.         if (!ptitel)
  4161.         {
  4162.             puts(title);
  4163.             ptitel++;
  4164.         }
  4165.  
  4166.         #if BETA
  4167.         if (!pargs)
  4168.         #else
  4169.         if (!pargs && (env=getenv("LHARCPAR"))!=NULL && atoi(env))
  4170.         #endif
  4171.         {
  4172.             register int i;
  4173.  
  4174.             pargs++;
  4175.             #if GERMAN
  4176.             puts("Argumente:");
  4177.             #else
  4178.             puts("Arguments:");
  4179.             #endif
  4180.             for (i=1;i<args;i++)
  4181.                 printf("'%s'\n",argv[i]);
  4182.             new_line();
  4183.         }
  4184.     }
  4185. }
  4186. #endif
  4187.  
  4188. uchar *get_ext(void)
  4189. {
  4190.     if (case_sensitive(arcname)==_PC_CASECONV)
  4191.         return(".LZH");
  4192.     else
  4193.         return(".lzh");
  4194. }
  4195.  
  4196. uchar *device(uchar *name)
  4197. {
  4198.     if (name[3]==':')
  4199.         name[3]='\0';
  4200.  
  4201.     if (!stricmp(name,"PRN") || !stricmp(name,"PRT"))
  4202.         return("PRN:");
  4203.     else if (!stricmp(name,"AUX"))
  4204.         return("AUX:");
  4205.     else if (!stricmp(name,"CON"))
  4206.         return("CON:");
  4207.     else
  4208.     {
  4209.         Convert_Filename(name,NULL,-1);
  4210.         return(name);
  4211.     }
  4212. }
  4213.  
  4214. int dev_arc(void)
  4215. {
  4216.     register uchar buf[MAXPATH],*path;
  4217.  
  4218.     if (__mint)
  4219.     {
  4220.         if (get_fname(arcname)==arcname)
  4221.             path=act_dir;
  4222.         else
  4223.             path=arcname;
  4224.  
  4225.         if (path[0]=='\0' || path[1]!=':')
  4226.         {
  4227.             buf[0]=Dgetdrv()+'a';
  4228.             buf[1]=':';
  4229.             if (path[0]!='\\')
  4230.             {
  4231.                 buf[2]='\\';
  4232.                 strcpy(buf+3,path);
  4233.             }
  4234.             else
  4235.                 strcpy(buf+2,path);
  4236.         }
  4237.         else
  4238.             strcpy(buf,path);
  4239.  
  4240.         strupr(buf);
  4241.  
  4242.         if (buf[0]=='U')
  4243.         {
  4244.             if (!strncmp(buf+3,"DEV\\",4))
  4245.                 return(1);
  4246.             else if (!strncmp(buf+3,"SHM\\",4) || !strncmp(buf+3,"PROC\\",5) || !strncmp(buf+3,"PIPE\\",5))
  4247.                 return(-1);
  4248.         }
  4249.     }
  4250.  
  4251.     return(0);
  4252. }
  4253.  
  4254. #ifndef __SHELL__
  4255. void ioredirect(int argc,uchar **argv)
  4256. {
  4257.     register uchar *p,c;
  4258.     register int i;
  4259.  
  4260.     for (i=0;i<argc;i++)
  4261.     {
  4262.         p=*argv++;
  4263.  
  4264.         if ((c=*p++)=='>' && o_handle<0)
  4265.         {
  4266.             if (!args)
  4267.                 args=i;
  4268.  
  4269.             if (*p=='>')
  4270.             {
  4271.                 if ((o_handle=Fopen(o_dir=device(++p),1))>=0)
  4272.                 {
  4273.                     o_dev=Fdup(1);
  4274.                     Fseek(0l,(int) o_handle,SEEK_END);
  4275.                     Fforce(1,(int) o_handle);
  4276.                     continue;
  4277.                 }
  4278.             }
  4279.  
  4280.             if ((o_handle=Fcreate(o_dir=device(p),0))>=0)
  4281.             {
  4282.                 o_dev=Fdup(1);
  4283.                 Fforce(1,(int) o_handle);
  4284.             }
  4285.         }
  4286.         else if (c=='<' && i_handle<0)
  4287.         {
  4288.             if (!args)
  4289.                 args=i;
  4290.  
  4291.             if ((i_handle=Fopen(p,0))>=0)
  4292.             {
  4293.                 i_dev=Fdup(0);
  4294.                 Fforce(0,(int) i_handle);
  4295.                 flg_m=1;
  4296.             }
  4297.         }
  4298.     }
  4299. }
  4300. #endif
  4301.  
  4302. #ifndef __SHELL__
  4303. void main(int argc,uchar **argv)
  4304. {
  4305.     register uchar *p,*q,*env,*env9,**old_argv=argv;
  4306.  
  4307.     ioredirect(argc,argv);
  4308.     if (args)
  4309.         argc=args;
  4310.     else
  4311.         args=argc;
  4312. #else
  4313. void argvmain(int argc,uchar **argv)
  4314. {
  4315.     register uchar *p,*q,*env,*env9;
  4316.  
  4317.     args=argc;
  4318. #endif
  4319.  
  4320.     if ((env=getenv("COLUMNS"))!=NULL)
  4321.     {
  4322.         maxblk=atoi(env) - 16;
  4323.         if (maxblk<24)
  4324.             maxblk=24;
  4325.     }
  4326.  
  4327.     argc--;
  4328. #ifndef __SHELL__
  4329.     if (argc<=0)
  4330.     {
  4331.         flg_h=1;
  4332.         puts(title_x);
  4333.         puts(use_1);
  4334.         wait_for_key(0);
  4335.         putchar('\r');
  4336.         puts(use_2);
  4337.         wait_for_key(0);
  4338.         putchar('\r');
  4339.         puts(use_3);
  4340.     }
  4341.     else
  4342. #endif
  4343.     {
  4344.         _lseed=clock();
  4345.         mkcrc();
  4346. #if __030
  4347.         get_cpu();
  4348. #endif
  4349.  
  4350.         Fsetdta(&_dta);
  4351.         getcwd(act_dir,MAXPATH);
  4352.         unix2dos(act_dir,0);
  4353.         slash(act_dir,1);
  4354.         Convert_Filename(act_dir,NULL,-1);
  4355.  
  4356.         fileptr=fileregbuf;
  4357.         *fileptr++='*';
  4358.         *fileptr++='\0';
  4359.  
  4360.         {
  4361.             register uint vers=Sversion();
  4362.             vers=(vers<<8) | (vers>>8);
  4363.  
  4364.             if (__mint)
  4365.                 oldtos=0;
  4366.             else
  4367.                 oldtos=(vers<0x0014);
  4368.         }
  4369.  
  4370.         buffer_gen=(uchar *) (((long) (buffer+128)) & (~15l));
  4371.  
  4372.         argv++;
  4373.         argc--;
  4374.         cmd=toupper(*(p=*argv++));
  4375.  
  4376.     #ifndef __SHELL__
  4377.         if (p[1]!='\0' || strchr("EXTDLVAUMFPRSC",cmd)==NULL || !argc)
  4378.         {
  4379.             register uchar dir[MAXPATH];
  4380.             register int compr;
  4381.  
  4382.             Convert_Filename(p,NULL,-1);
  4383.             if ((q=strstr(p,"*.*"))>NULL)
  4384.             {
  4385.                 if (q==p)
  4386.                     p=strcpy(dir,act_dir);
  4387.                 else
  4388.                     *q='\0';
  4389.             }
  4390.             slash(p,0);
  4391.  
  4392.             if (Attrib(p)>0)
  4393.                 compr=1;
  4394.             else
  4395.             {
  4396.                 switch (test_afx(p))
  4397.                 {
  4398.                 case 3:
  4399.                     {
  4400.                         register uchar *b=buffer_gen;
  4401.                         
  4402.                         q=b+1536;
  4403.                         compr=1;
  4404.  
  4405.                         while (b<q)
  4406.                         {
  4407.                             if (!strncmp(b,"SFX",3))
  4408.                                 goto _extract;
  4409.                             else if (*b++=='-' && b[3]=='-' && (*b=='a' || *b=='A' || *b=='l' || *b=='L'))
  4410.                                 break;
  4411.                         }
  4412.                     }
  4413.                     break;
  4414.                 case 2:
  4415.                     _extract:
  4416.                     compr=0;
  4417.                     break;
  4418.                 default:
  4419.                     compr=1;
  4420.                 }
  4421.             }
  4422.  
  4423.             if (strpbrk(get_fname(p),"*?")==NULL && compr)
  4424.             {
  4425.                 cmd='U';
  4426.                 pack++;
  4427.  
  4428.                 strcpy(arcname,p);
  4429.                 p=get_fname(p);
  4430.                 if ((q=strrchr(p,'.'))!=NULL)
  4431.                     *q='\0';
  4432.  
  4433.                 strcpy(stpcpy(backpath(arcname),p),get_ext());
  4434.  
  4435.                 if (q)
  4436.                     *q='.';
  4437.             }
  4438.             else
  4439.             {
  4440.                 cmd='X';
  4441.                 flg_g++;
  4442.                 backpath(strcpy(basedir,p));
  4443.                 pack+=2;
  4444.             }
  4445.  
  4446.             flg_x=3;
  4447.             flg_m++;
  4448.             argc++;
  4449.             argv--;
  4450.         }
  4451.     #endif
  4452.  
  4453.         cmdupdate=strchr("AUMFRD",cmd)!=NULL;
  4454.         cmdlist=strchr("AUMC",cmd)!=NULL;
  4455.  
  4456.         if ((env=getenv("TMP"))!=NULL || (env=getenv("TMPDIR"))!=NULL)
  4457.         {
  4458.             flg_w++;
  4459.             strcpy(workdir,env);
  4460.         }
  4461.  
  4462.         if ((env=getenv("UNPACKED"))!=NULL)
  4463.         {
  4464.             flg_U++;
  4465.             unpack=env;
  4466.         }
  4467.  
  4468.         if ((env=getenv("LHARC"))!=NULL)
  4469.         {
  4470.             for (p=env;*p;p++)
  4471.                 if (*p==' ' || *p=='\x08')
  4472.                     *p=0;
  4473.             env9=p;
  4474.             p=env;
  4475.             while (p<env9)
  4476.             {
  4477.                 while (!*p)
  4478.                     p++;
  4479.                 if (*p=='-' || *p=='/')
  4480.                     p++;
  4481.                 getsw(p);
  4482.                 while (*p)
  4483.                     p++;
  4484.             }
  4485.         }
  4486.  
  4487.         if (cmd=='C' || arcname[0])
  4488.             patno=0;
  4489.         else
  4490.             patno=-1;
  4491.  
  4492.         while (argc--)
  4493.         {
  4494.             p=*argv++;
  4495.             if (*p=='-')
  4496.             {
  4497.                 getsw(++p);
  4498.                 continue;
  4499.             }
  4500.             else if (*p=='/' && patno<0 && tstsw(p+1))
  4501.             {
  4502.                 if (cmdupdate && (wildcard(get_fname(p+1)) || multi_wild(p+1)))
  4503.                 {
  4504.                     getsw(++p);
  4505.                     continue;
  4506.                 }
  4507.                 else if ((q=strrchr(get_fname(p),'.'))!=NULL)
  4508.                 {
  4509.                     if (arc_ext(q)==FAULT)
  4510.                     {
  4511.                         getsw(++p);
  4512.                         continue;
  4513.                     }
  4514.                 }
  4515.                 else
  4516.                 {
  4517.                     getsw(++p);
  4518.                     continue;
  4519.                 }
  4520.             }
  4521.  
  4522.             print_title(old_argv);
  4523.             Convert_Filename(p,NULL,-1);
  4524.  
  4525.             if (patno<0)
  4526.             {
  4527.                 p=get_fname(strcpy(arcname,p));
  4528.  
  4529.                 if (*p=='\0' || (Device=dev_arc())<0)
  4530.                     error(NOARCNMERR,NULL,SUCCS);
  4531.  
  4532.                 multi_arc=multi_wild(p);
  4533.                 wild_arc=wildcard(p)|multi_arc;
  4534.  
  4535.                 if (cmdupdate && (strpbrk(p,"*?") || multi_arc))
  4536.                     error(NOARCNMERR,arcname,SUCCS);
  4537.  
  4538.                 if (!multi_arc && !Device)
  4539.                 {
  4540.                     if ((q=strrchr(p,'.'))==NULL)
  4541.                         strcat(arcname,get_ext());
  4542.                     else if (q[1]=='\0')
  4543.                         strcpy(q,get_ext());
  4544.                     else if (flg_m!=1 && cmdupdate && arc_ext(q)==FAULT)
  4545.                     {
  4546.                         printf(M_NOTLZH,get_fname(arcname));
  4547.                         if (get_key("YN")=='N')
  4548.                         {
  4549.                             errorlevel|=128;
  4550.                             lha_exit();
  4551.                         }
  4552.                     }
  4553.                 }
  4554.                 patno++;
  4555.             }
  4556.             else if (pack<2)
  4557.             {
  4558.                 if (pack)
  4559.                 {
  4560.                     slash(p,0);
  4561.  
  4562.                     if (strstr(p,"*.*")!=NULL)
  4563.                         flg_r++;
  4564.                     else if (Attrib(p)>0)
  4565.                     {
  4566.                         register uchar path[MAXPATH];
  4567.  
  4568.                         flg_r++;
  4569.                         slash(strcpy(path,p),1);
  4570.                         if ((p=strdup(path))==NULL)
  4571.                             error(MEMOVRERR,NULL,SUCCS);
  4572.                     }
  4573.                 }
  4574.  
  4575.                 newfile(p);
  4576.             }
  4577.         }
  4578.  
  4579.         if (args>2 && pack==1)
  4580.             pack=0;
  4581.         else if (pack==2)
  4582.             pack=0;
  4583.  
  4584.         print_title(old_argv);
  4585.  
  4586.         if (patno<0)
  4587.             error(NOARCNMERR,NULL,SUCCS);
  4588.         else if (!patno && cmd!='D')
  4589.         {
  4590.             travel_path[0]="";
  4591.             travel_len[0]=travel_file[0]=travel_rel[0]=0;
  4592.             travel_wild[0]=all=SUCCS;
  4593.             patno++;
  4594.             flg_p=0;
  4595.         }
  4596.  
  4597.         fn_name=path_conf(basedir,_PC_NAME_MAX);
  4598.         pt_name=path_conf(basedir,_PC_PATH_MAX);
  4599.         if (pt_name>MAXPATH)
  4600.             pt_name=MAXPATH;
  4601.         Case=case_sensitive(basedir);
  4602.  
  4603.         if (flg_U)
  4604.             Convert_Filename(unpack,NULL,0);
  4605.  
  4606.         Convert_Filename(workdir,NULL,0);
  4607.         slash(workdir,1);
  4608.         tstdir(workdir,-1);
  4609.  
  4610.         Convert_Filename(incldir,NULL,0);
  4611.         slash(incldir,1);
  4612.  
  4613.         if (Device)
  4614.         {
  4615.             if (strchr("AMEXTPLV",cmd)==NULL)
  4616.                 error(NOARCERR,arcname,SUCCS);
  4617.             else if (strchr("EXTP",cmd))
  4618.                 flg_d=0;
  4619.             flg_w=0;
  4620.         }
  4621.  
  4622.         MakeBuffers();
  4623.  
  4624.         if (cmdupdate || cmd=='C')
  4625.             executecmd();
  4626.         else
  4627.         {
  4628.             register uchar *f,*p,*q,arc[MAXPATH];
  4629.             register long handle,buf[MAXPATH>>2];
  4630.             register int done,cnt=0,len,case_s;
  4631.  
  4632.             if (__mint)
  4633.                 _gemdos=(path_conf(arcname,_PC_NAME_MAX)<=12 && case_sensitive(arcname)==_PC_CASECONV) ? 1 : 0;
  4634.             else
  4635.                 _gemdos=1;
  4636.  
  4637.             if (!_gemdos)
  4638.             {
  4639.                 backpath(strcpy(arc,arcname));
  4640.  
  4641.                 if (arc[0]!='\0')
  4642.                     handle=Dopendir(arc,0);
  4643.                 else
  4644.                     handle=Dopendir(act_dir,0);
  4645.  
  4646.                 if ((handle&0xff000000l)==0xff000000l)
  4647.                     error(NOARCERR,arcname,SUCCS);
  4648.                 else
  4649.                     done=(int) Dreaddir(MAXPATH,handle,(uchar *) buf);
  4650.                 f=(uchar *) &buf[1];
  4651.             }
  4652.             else
  4653.             {
  4654.                 strcpy(arc,arcname);
  4655.                 if (wild_arc)
  4656.                     strcpy(backpath(arc),"*.*");
  4657.                 done=Fsfirst(arc,0x07);
  4658.                 f=_dta.dta_name;
  4659.             }
  4660.  
  4661.             case_s=(flg_S==2 || (!flg_S && case_sensitive(arcname)!=_PC_CASESENS));
  4662.             q=get_fname(arcname);
  4663.             p=backpath(arc);
  4664.  
  4665.             while(!done)
  4666.             {
  4667.                 if (case_s)
  4668.                     strupr(f);
  4669.  
  4670.                 if ((_gemdos && wild_arc==FAULT) || chk_wild(f,q,flg_W))
  4671.                 {
  4672.                     strcpy(p,f);
  4673.                     if (o_dir!=NULL && !strcmp(p,o_dir))
  4674.                         goto arc_next;
  4675.  
  4676.                     if (!_gemdos)
  4677.                     {
  4678.                         if (*f!='.' || (strcmp(f,".") && strcmp(f,"..")))
  4679.                         {
  4680.                             Fxattr(0,arc,(uchar *) &xattr);
  4681.                             if (xattr.attr & (FA_LABEL|FA_DIR))
  4682.                                 goto arc_next;
  4683.                             *p='\0';
  4684.                         }
  4685.                         else
  4686.                             goto arc_next;
  4687.                     }
  4688.  
  4689.                     if (cnt<MAX_ARC)
  4690.                     {
  4691.                         len=(int) strlen(f)+1;
  4692.                         if ((fileptr-fileregbuf+len)>=(FILEBUFSIZ-1))
  4693.                             message(M_FILETAB,f);
  4694.                         else
  4695.                         {
  4696.                             strcpy(fileptr,f);
  4697.                             arc_file[cnt++]=(int) (fileptr-fileregbuf);
  4698.                             fileptr+=len;
  4699.                         }
  4700.                     }
  4701.                     else
  4702.                         message(M_FILETAB,f);
  4703.                 }
  4704.  
  4705.                 arc_next:
  4706.                 if (_gemdos)
  4707.                     done=Fsnext();
  4708.                 else
  4709.                     done=(int) Dreaddir(MAXPATH,handle,(uchar *) buf);
  4710.             }
  4711.  
  4712.             if (!_gemdos)
  4713.                 Dclosedir(handle);
  4714.  
  4715.             if (!cnt)
  4716.                 error(NOARCERR,arcname,SUCCS);
  4717.             else
  4718.             {
  4719.                 if (!flg_q)
  4720.                 #if GERMAN
  4721.                     printf(" Archive gefunden : %d\n",cnt);
  4722.                 #else
  4723.                     printf(" Archives matched : %d\n",cnt);
  4724.                 #endif
  4725.  
  4726.                 q=basedir+strlen(basedir);
  4727.  
  4728.                 while(--cnt>=0)
  4729.                 {
  4730.                     f=&fileregbuf[arc_file[cnt]];
  4731.                     strcpy(backpath(arcname),f);
  4732.                     if (cmd=='X' || cmd=='E')
  4733.                     {
  4734.                         if (flg_g && (p=strrchr(f,'.'))!=NULL)
  4735.                         {
  4736.                             *p='\0';
  4737.                             strcpy(stpcpy(q,f),"\\");
  4738.                         }
  4739.  
  4740.                         tstdir(basedir,-1);
  4741.                     }
  4742.  
  4743.                     executecmd();
  4744.                 }
  4745.             }
  4746.  
  4747.             if (cmd!='L' && cmd!='V')
  4748.                 tstpat();
  4749.         }
  4750.     }
  4751.  
  4752.     lha_exit();
  4753. }
  4754.